summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSrikar Srimath Tirumala <srikars@nvidia.com>2017-01-11 18:35:21 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-02-07 19:04:39 -0500
commit3335ff9fe90d3f523a463107bae864b011590182 (patch)
tree2d7d85333c4d9c19b8fa40a2881e3610ce10827d /drivers
parent521253acb761041a5d9ba97a7a789fe02682a03d (diff)
gpu: nvgpu: add support for EMC freq scaling
Add support to do EMC frequency scaling via bwmgr on T210 K4.4. Bug 200267304 Change-Id: Ib01f1a256cfceefc5551e128b7ba8953fafe21d3 Signed-off-by: Srikar Srimath Tirumala <srikars@nvidia.com> Reviewed-on: http://git-master/r/1285001 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Peter Boonstoppel <pboonstoppel@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Jon Mayo <jmayo@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c91
1 files changed, 87 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
index c18f0230..a373f487 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c
@@ -38,6 +38,9 @@
38#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) 38#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
39#include <soc/tegra/fuse.h> 39#include <soc/tegra/fuse.h>
40#endif 40#endif
41#ifdef CONFIG_TEGRA_BWMGR
42#include <linux/platform/tegra/emc_bwmgr.h>
43#endif
41 44
42#include <linux/platform/tegra/tegra_emc.h> 45#include <linux/platform/tegra/tegra_emc.h>
43 46
@@ -62,10 +65,18 @@
62 65
63extern struct device tegra_vpr_dev; 66extern struct device tegra_vpr_dev;
64 67
68#ifdef CONFIG_TEGRA_BWMGR
65struct gk20a_emc_params { 69struct gk20a_emc_params {
66 unsigned long bw_ratio; 70 unsigned long bw_ratio;
67 unsigned long freq_last_set; 71 unsigned long freq_last_set;
72 struct tegra_bwmgr_client *bwmgr_cl;
68}; 73};
74#else
75struct gk20a_emc_params {
76 unsigned long bw_ratio;
77 unsigned long freq_last_set;
78};
79#endif
69 80
70static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); 81static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
71static inline u32 __maybe_unused pmc_read(unsigned long reg) 82static inline u32 __maybe_unused pmc_read(unsigned long reg)
@@ -317,6 +328,51 @@ static void gk20a_tegra_calibrate_emc(struct device *dev,
317 emc_params->bw_ratio = (gpu_bw / emc_bw); 328 emc_params->bw_ratio = (gpu_bw / emc_bw);
318} 329}
319 330
331#ifdef CONFIG_TEGRA_BWMGR
332void gm20b_bwmgr_set_rate(struct gk20a_platform *platform, bool enb)
333{
334 struct gk20a_scale_profile *profile = platform->g->scale_profile;
335 struct gk20a_emc_params *params;
336 unsigned long rate;
337
338 if (!profile || !profile->private_data)
339 return;
340
341 params = (struct gk20a_emc_params *)profile->private_data;
342 rate = (enb) ? params->freq_last_set : 0;
343 tegra_bwmgr_set_emc(params->bwmgr_cl, rate, TEGRA_BWMGR_SET_EMC_FLOOR);
344}
345
346static void gm20b_tegra_postscale(struct device *dev, unsigned long freq)
347{
348 struct gk20a_platform *platform = dev_get_drvdata(dev);
349 struct gk20a_scale_profile *profile = platform->g->scale_profile;
350 struct gk20a_emc_params *emc_params;
351 unsigned long emc_rate;
352
353 if (!profile)
354 return;
355
356 emc_params = profile->private_data;
357 emc_rate = gk20a_tegra_get_emc_rate(get_gk20a(dev), emc_params);
358
359 if (emc_rate > tegra_bwmgr_get_max_emc_rate())
360 emc_rate = tegra_bwmgr_get_max_emc_rate();
361
362 emc_params->freq_last_set = emc_rate;
363 mutex_lock(&platform->railgate_lock);
364 if (platform->is_railgated && !platform->is_railgated(dev))
365 goto done;
366
367 tegra_bwmgr_set_emc(emc_params->bwmgr_cl, emc_rate,
368 TEGRA_BWMGR_SET_EMC_FLOOR);
369
370done:
371 mutex_unlock(&platform->railgate_lock);
372}
373
374#endif
375
320#ifdef CONFIG_TEGRA_CLK_FRAMEWORK 376#ifdef CONFIG_TEGRA_CLK_FRAMEWORK
321/* 377/*
322 * gk20a_tegra_railgate() 378 * gk20a_tegra_railgate()
@@ -463,7 +519,6 @@ static bool gk20a_tegra_is_railgated(struct device *dev)
463 return ret; 519 return ret;
464} 520}
465 521
466
467/* 522/*
468 * gm20b_tegra_railgate() 523 * gm20b_tegra_railgate()
469 * 524 *
@@ -514,6 +569,10 @@ static int gm20b_tegra_railgate(struct device *dev)
514 } else 569 } else
515 pr_info("No GPU regulator?\n"); 570 pr_info("No GPU regulator?\n");
516 571
572#ifdef CONFIG_TEGRA_BWMGR
573 gm20b_bwmgr_set_rate(platform, false);
574#endif
575
517 return 0; 576 return 0;
518 577
519err_power_off: 578err_power_off:
@@ -552,6 +611,10 @@ static int gm20b_tegra_unrailgate(struct device *dev)
552 if (ret) 611 if (ret)
553 return ret; 612 return ret;
554 613
614#ifdef CONFIG_TEGRA_BWMGR
615 gm20b_bwmgr_set_rate(platform, true);
616#endif
617
555 tegra_soctherm_gpu_tsens_invalidate(0); 618 tegra_soctherm_gpu_tsens_invalidate(0);
556 619
557 if (!platform->clk_reset) { 620 if (!platform->clk_reset) {
@@ -750,6 +813,14 @@ static void gk20a_tegra_scale_init(struct device *dev)
750 emc_params->freq_last_set = -1; 813 emc_params->freq_last_set = -1;
751 gk20a_tegra_calibrate_emc(dev, emc_params); 814 gk20a_tegra_calibrate_emc(dev, emc_params);
752 815
816#ifdef CONFIG_TEGRA_BWMGR
817 emc_params->bwmgr_cl = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_GPU);
818 if (!emc_params->bwmgr_cl) {
819 gk20a_dbg_info("%s Missing GPU BWMGR client\n", __func__);
820 return;
821 }
822#endif
823
753 profile->private_data = emc_params; 824 profile->private_data = emc_params;
754} 825}
755 826
@@ -757,9 +828,17 @@ static void gk20a_tegra_scale_exit(struct device *dev)
757{ 828{
758 struct gk20a_platform *platform = dev_get_drvdata(dev); 829 struct gk20a_platform *platform = dev_get_drvdata(dev);
759 struct gk20a_scale_profile *profile = platform->g->scale_profile; 830 struct gk20a_scale_profile *profile = platform->g->scale_profile;
831 struct gk20a_emc_params *emc_params;
832
833 if (!profile)
834 return;
760 835
761 if (profile) 836 emc_params = profile->private_data;
762 kfree(profile->private_data); 837#ifdef CONFIG_TEGRA_BWMGR
838 tegra_bwmgr_unregister(emc_params->bwmgr_cl);
839#endif
840
841 kfree(profile->private_data);
763} 842}
764 843
765void gk20a_tegra_debug_dump(struct device *dev) 844void gk20a_tegra_debug_dump(struct device *dev)
@@ -1027,9 +1106,9 @@ struct gk20a_platform gm20b_tegra_platform = {
1027 .probe = gk20a_tegra_probe, 1106 .probe = gk20a_tegra_probe,
1028 .late_probe = gk20a_tegra_late_probe, 1107 .late_probe = gk20a_tegra_late_probe,
1029 .remove = gk20a_tegra_remove, 1108 .remove = gk20a_tegra_remove,
1030
1031 /* power management callbacks */ 1109 /* power management callbacks */
1032 .suspend = gk20a_tegra_suspend, 1110 .suspend = gk20a_tegra_suspend,
1111
1033#if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_TEGRA_DVFS) 1112#if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_TEGRA_DVFS)
1034 .railgate = gm20b_tegra_railgate, 1113 .railgate = gm20b_tegra_railgate,
1035 .unrailgate = gm20b_tegra_unrailgate, 1114 .unrailgate = gm20b_tegra_unrailgate,
@@ -1060,7 +1139,11 @@ struct gk20a_platform gm20b_tegra_platform = {
1060 1139
1061 /* frequency scaling configuration */ 1140 /* frequency scaling configuration */
1062 .prescale = gk20a_tegra_prescale, 1141 .prescale = gk20a_tegra_prescale,
1142#ifdef CONFIG_TEGRA_BWMGR
1143 .postscale = gm20b_tegra_postscale,
1144#else
1063 .postscale = gk20a_tegra_postscale, 1145 .postscale = gk20a_tegra_postscale,
1146#endif
1064 .devfreq_governor = "nvhost_podgov", 1147 .devfreq_governor = "nvhost_podgov",
1065 .qos_notify = gk20a_scale_qos_notify, 1148 .qos_notify = gk20a_scale_qos_notify,
1066 1149