summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Longnecker <mlongnecker@nvidia.com>2014-08-18 17:00:01 -0700
committerWinnie Hsu <whsu@nvidia.com>2014-09-19 10:13:19 -0700
commit027d2646851ad2810a96db9d63d80bb333a543f0 (patch)
tree9b86bb54c6aa2a97b4c02bf4b34b116dfa8fc983
parentd758be8cb8f3f3a06ec1b4042b1af09c8c5de536 (diff)
edp: sysedp : CPU/GPU priority depends on fGPU
Provide sysedp_dynamic_capping with the instantaneous GPU frequency when notifying it of the GPU load. Modify the gpu/cpu priority decision logic to choose CPU priority until GPU frequency gets "near" the CPU-priority-limited-GPU-fmax. Introduce the priority_bias debugfs parameter to facilitate tuning of "near". priority_bias takes a value from 0 to 100. Change-Id: I57df17d50cd8077a512b5932f4a304ca5e6992aa Signed-off-by: Matt Longnecker <mlongnecker@nvidia.com> Reviewed-on: http://git-master/r/481720 (cherry picked from commit b2ac745a45e273e849d7b190913ee97092fdebc2) Reviewed-on: http://git-master/r/498901 GVS: Gerrit_Virtual_Submit Reviewed-by: Winnie Hsu <whsu@nvidia.com>
-rw-r--r--drivers/edp/sysedp_dynamic_capping.c13
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c4
-rw-r--r--drivers/video/tegra/host/nvhost_acm.c2
-rw-r--r--drivers/video/tegra/host/nvhost_scale.c4
-rw-r--r--include/linux/platform_data/tegra_edp.h4
5 files changed, 18 insertions, 9 deletions
diff --git a/drivers/edp/sysedp_dynamic_capping.c b/drivers/edp/sysedp_dynamic_capping.c
index 1860c5524faf..9c0160e98df3 100644
--- a/drivers/edp/sysedp_dynamic_capping.c
+++ b/drivers/edp/sysedp_dynamic_capping.c
@@ -39,8 +39,10 @@ static unsigned int gpu_high_threshold = 500;
static unsigned int gpu_window = 80;
static unsigned int gpu_high_hist;
static unsigned int gpu_high_count = 2;
+static unsigned int priority_bias = 75;
static unsigned int online_cpu_count;
static bool gpu_busy;
+static unsigned int fgpu;
static unsigned int avail_power;
static unsigned int avail_oc_relax;
static unsigned int cap_method;
@@ -161,7 +163,9 @@ static void apply_caps(struct tegra_sysedp_devcap *devcap)
static inline bool gpu_priority(void)
{
- return gpu_busy || force_gpu_pri;
+ return (force_gpu_pri ||
+ (gpu_busy &&
+ (fgpu > cur_corecap->cpupri.gpufreq * priority_bias / 100)));
}
static inline struct tegra_sysedp_devcap *get_devcap(void)
@@ -271,12 +275,13 @@ static bool calc_gpu_busy(unsigned int load)
return (gpu_high_hist & mask) == mask;
}
-void tegra_edp_notify_gpu_load(unsigned int load)
+void tegra_edp_notify_gpu_load(unsigned int load, unsigned int freq_in_hz)
{
bool old;
old = gpu_busy;
gpu_busy = calc_gpu_busy(load);
+ fgpu = freq_in_hz / 1000;
if (gpu_busy == old || force_gpu_pri || !capping_device_platdata)
return;
@@ -310,9 +315,10 @@ static int tegra_edp_cpu_notify(struct notifier_block *nb,
}
static struct notifier_block tegra_edp_cpu_nb = {
- .notifier_call = tegra_edp_cpu_notify
+ .notifier_call = tegra_edp_cpu_notify
};
+
#ifdef CONFIG_DEBUG_FS
static struct dentry *capping_debugfs_dir;
@@ -499,6 +505,7 @@ static void init_debug(void)
create_attr("gain", &capping_device_platdata->core_gain);
create_attr("gpu_high_count", &gpu_high_count);
create_attr("cap_method", &cap_method);
+ create_attr("priority_bias", &priority_bias);
create_longattr("corecaps", corecaps_show);
create_longattr("cpucaps", cpucaps_show);
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
index a20ad8f116a1..edeacdac6e5c 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
@@ -238,7 +238,7 @@ static void gk20a_tegra_prescale(struct platform_device *pdev)
u32 avg = 0;
gk20a_pmu_load_norm(g, &avg);
- tegra_edp_notify_gpu_load(avg);
+ tegra_edp_notify_gpu_load(avg, gk20a_clk_get_rate(g));
}
/*
@@ -477,7 +477,7 @@ static int gk20a_tegra_late_probe(struct platform_device *dev)
static int gk20a_tegra_suspend(struct device *dev)
{
- tegra_edp_notify_gpu_load(0);
+ tegra_edp_notify_gpu_load(0, 0);
return 0;
}
diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c
index 36b54b7a1d59..2695268aeff3 100644
--- a/drivers/video/tegra/host/nvhost_acm.c
+++ b/drivers/video/tegra/host/nvhost_acm.c
@@ -615,7 +615,7 @@ int nvhost_module_suspend(struct device *dev)
/* inform edp governor that there is no load any more */
if (pdata->gpu_edp_device)
- tegra_edp_notify_gpu_load(0);
+ tegra_edp_notify_gpu_load(0, 0);
return 0;
}
diff --git a/drivers/video/tegra/host/nvhost_scale.c b/drivers/video/tegra/host/nvhost_scale.c
index 4129c566c92c..51e94251e3c3 100644
--- a/drivers/video/tegra/host/nvhost_scale.c
+++ b/drivers/video/tegra/host/nvhost_scale.c
@@ -222,7 +222,9 @@ static void nvhost_scale_notify(struct platform_device *pdev, bool busy)
if (pdata->gpu_edp_device) {
u32 avg = 0;
actmon_op().read_avg_norm(profile->actmon, &avg);
- tegra_edp_notify_gpu_load(avg);
+ BUG();
+ /* the next line passes a bogus frequency */
+ tegra_edp_notify_gpu_load(avg, 0);
}
/* If defreq is disabled, set the freq to max or min */
diff --git a/include/linux/platform_data/tegra_edp.h b/include/linux/platform_data/tegra_edp.h
index ecee6f02a791..db020fccdc46 100644
--- a/include/linux/platform_data/tegra_edp.h
+++ b/include/linux/platform_data/tegra_edp.h
@@ -59,9 +59,9 @@ struct tegra_sysedp_platform_data {
};
#if defined(CONFIG_EDP_FRAMEWORK) || defined(CONFIG_SYSEDP_FRAMEWORK)
-void tegra_edp_notify_gpu_load(unsigned int load);
+void tegra_edp_notify_gpu_load(unsigned int load, unsigned int freq_in_hz);
#else
-static inline void tegra_edp_notify_gpu_load(unsigned int load) {}
+static inline void tegra_edp_notify_gpu_load(unsigned int load, unsigned int freq_in_hz) {}
#endif
#endif