summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2014-06-12 06:46:15 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:22 -0400
commit6dc277b783bca9170c43c725884878ba63ce64da (patch)
tree0ddfba648ff4cce95ec9a28dc297e42ccd73df9b /drivers
parent0f9bf924b2be88502c9920ace258c27e0172e3d5 (diff)
gpu:nvgpu:sysfs node to update aelpg parameter
Added sysfs node to update aelpg parameter. Pass parameter as below sequence, SAMPLING_PERIOD_PG_DEFAULT_US, MINIMUM_IDLE_FILTER_DEFAULT_US, MINIMUM_TARGET_SAVING_DEFAULT_US, POWER_BREAKEVEN_DEFAULT_US, CYCLES_PER_SAMPLE_MAX_DEFAULT Bug 1464737 Change-Id: I46873c463820f30f190c722d7ed038622cb2710f Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/422702 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c7
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c59
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c23
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.h6
4 files changed, 80 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index c72b8735..3388a2ff 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -1539,6 +1539,13 @@ static int gk20a_probe(struct platform_device *dev)
1539 gk20a->aelpg_enabled = 1539 gk20a->aelpg_enabled =
1540 tegra_platform_is_silicon() ? platform->enable_aelpg : false; 1540 tegra_platform_is_silicon() ? platform->enable_aelpg : false;
1541 1541
1542 /* set default values to aelpg parameters */
1543 gk20a->pmu.aelpg_param[0] = APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US;
1544 gk20a->pmu.aelpg_param[1] = APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US;
1545 gk20a->pmu.aelpg_param[2] = APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US;
1546 gk20a->pmu.aelpg_param[3] = APCTRL_POWER_BREAKEVEN_DEFAULT_US;
1547 gk20a->pmu.aelpg_param[4] = APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT;
1548
1542 gk20a_create_sysfs(dev); 1549 gk20a_create_sysfs(dev);
1543 1550
1544#ifdef CONFIG_DEBUG_FS 1551#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
index eb0aa5d1..2debe235 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
@@ -29,6 +29,7 @@
29#include "gk20a.h" 29#include "gk20a.h"
30#include "gr_gk20a.h" 30#include "gr_gk20a.h"
31#include "fifo_gk20a.h" 31#include "fifo_gk20a.h"
32#include "pmu_gk20a.h"
32 33
33 34
34#define PTIMER_FP_FACTOR 1000000 35#define PTIMER_FP_FACTOR 1000000
@@ -332,6 +333,62 @@ static ssize_t elpg_enable_read(struct device *device,
332 333
333static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store); 334static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store);
334 335
336static ssize_t aelpg_param_store(struct device *device,
337 struct device_attribute *attr, const char *buf, size_t count)
338{
339 struct platform_device *ndev = to_platform_device(device);
340 struct gk20a *g = get_gk20a(ndev);
341 int status = 0;
342 union pmu_ap_cmd ap_cmd;
343 int *paramlist = (int *)g->pmu.aelpg_param;
344 u32 defaultparam[5] = {
345 APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US,
346 APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US,
347 APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US,
348 APCTRL_POWER_BREAKEVEN_DEFAULT_US,
349 APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT
350 };
351
352 /* Get each parameter value from input string*/
353 sscanf(buf, "%d %d %d %d %d", &paramlist[0], &paramlist[1],
354 &paramlist[2], &paramlist[3], &paramlist[4]);
355
356 /* If parameter value is 0 then reset to SW default values*/
357 if ((paramlist[0] | paramlist[1] | paramlist[2]
358 | paramlist[3] | paramlist[4]) == 0x00) {
359 memcpy(paramlist, defaultparam, sizeof(defaultparam));
360 }
361
362 /* If aelpg is enabled & pmu is ready then post values to
363 * PMU else store then post later
364 */
365 if (g->aelpg_enabled && g->pmu.pmu_ready) {
366 /* Disable AELPG */
367 ap_cmd.init.cmd_id = PMU_AP_CMD_ID_DISABLE_CTRL;
368 status = gk20a_pmu_ap_send_command(g, &ap_cmd, false);
369
370 /* Enable AELPG */
371 gk20a_aelpg_init(g);
372 gk20a_aelpg_init_and_enable(g, PMU_AP_CTRL_ID_GRAPHICS);
373 }
374
375 return count;
376}
377
378static ssize_t aelpg_param_read(struct device *device,
379 struct device_attribute *attr, char *buf)
380{
381 struct platform_device *ndev = to_platform_device(device);
382 struct gk20a *g = get_gk20a(ndev);
383
384 return sprintf(buf, "%d %d %d %d %d\n", g->pmu.aelpg_param[0],
385 g->pmu.aelpg_param[1], g->pmu.aelpg_param[2],
386 g->pmu.aelpg_param[3], g->pmu.aelpg_param[4]);
387}
388
389static DEVICE_ATTR(aelpg_param, S_IRWXUGO,
390 aelpg_param_read, aelpg_param_store);
391
335#ifdef CONFIG_PM_RUNTIME 392#ifdef CONFIG_PM_RUNTIME
336static ssize_t force_idle_store(struct device *device, 393static ssize_t force_idle_store(struct device *device,
337 struct device_attribute *attr, const char *buf, size_t count) 394 struct device_attribute *attr, const char *buf, size_t count)
@@ -400,6 +457,7 @@ void gk20a_remove_sysfs(struct device *dev)
400#ifdef CONFIG_PM_RUNTIME 457#ifdef CONFIG_PM_RUNTIME
401 device_remove_file(dev, &dev_attr_force_idle); 458 device_remove_file(dev, &dev_attr_force_idle);
402#endif 459#endif
460 device_remove_file(dev, &dev_attr_aelpg_param);
403 461
404 if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev)) 462 if (g->host1x_dev && (dev->parent != &g->host1x_dev->dev))
405 sysfs_remove_link(&dev->kobj, dev_name(dev)); 463 sysfs_remove_link(&dev->kobj, dev_name(dev));
@@ -423,6 +481,7 @@ void gk20a_create_sysfs(struct platform_device *dev)
423#ifdef CONFIG_PM_RUNTIME 481#ifdef CONFIG_PM_RUNTIME
424 error |= device_create_file(&dev->dev, &dev_attr_force_idle); 482 error |= device_create_file(&dev->dev, &dev_attr_force_idle);
425#endif 483#endif
484 error |= device_create_file(&dev->dev, &dev_attr_aelpg_param);
426 485
427 if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev)) 486 if (g->host1x_dev && (dev->dev.parent != &g->host1x_dev->dev))
428 error |= sysfs_create_link(&g->host1x_dev->dev.kobj, 487 error |= sysfs_create_link(&g->host1x_dev->dev.kobj,
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index 808bf015..a5b9f05f 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -43,8 +43,6 @@ static int gk20a_pmu_get_elpg_residency_gating(struct gk20a *g,
43static void ap_callback_init_and_enable_ctrl( 43static void ap_callback_init_and_enable_ctrl(
44 struct gk20a *g, struct pmu_msg *msg, 44 struct gk20a *g, struct pmu_msg *msg,
45 void *param, u32 seq_desc, u32 status); 45 void *param, u32 seq_desc, u32 status);
46static int gk20a_pmu_ap_send_command(struct gk20a *g,
47 union pmu_ap_cmd *p_ap_cmd, bool b_block);
48 46
49static u32 pmu_cmdline_size_v0(struct pmu_gk20a *pmu) 47static u32 pmu_cmdline_size_v0(struct pmu_gk20a *pmu)
50{ 48{
@@ -1803,9 +1801,6 @@ int gk20a_init_pmu_setup_hw1(struct gk20a *g)
1803 1801
1804} 1802}
1805 1803
1806static int gk20a_aelpg_init(struct gk20a *g);
1807static int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id);
1808
1809static void pmu_setup_hw_load_zbc(struct gk20a *g); 1804static void pmu_setup_hw_load_zbc(struct gk20a *g);
1810static void pmu_setup_hw_enable_elpg(struct gk20a *g); 1805static void pmu_setup_hw_enable_elpg(struct gk20a *g);
1811 1806
@@ -3441,7 +3436,7 @@ static int gk20a_pmu_get_elpg_residency_gating(struct gk20a *g,
3441} 3436}
3442 3437
3443/* Send an Adaptive Power (AP) related command to PMU */ 3438/* Send an Adaptive Power (AP) related command to PMU */
3444static int gk20a_pmu_ap_send_command(struct gk20a *g, 3439int gk20a_pmu_ap_send_command(struct gk20a *g,
3445 union pmu_ap_cmd *p_ap_cmd, bool b_block) 3440 union pmu_ap_cmd *p_ap_cmd, bool b_block)
3446{ 3441{
3447 struct pmu_gk20a *pmu = &g->pmu; 3442 struct pmu_gk20a *pmu = &g->pmu;
@@ -3545,7 +3540,7 @@ static void ap_callback_init_and_enable_ctrl(
3545 } 3540 }
3546} 3541}
3547 3542
3548static int gk20a_aelpg_init(struct gk20a *g) 3543int gk20a_aelpg_init(struct gk20a *g)
3549{ 3544{
3550 int status = 0; 3545 int status = 0;
3551 3546
@@ -3554,30 +3549,28 @@ static int gk20a_aelpg_init(struct gk20a *g)
3554 3549
3555 /* TODO: Check for elpg being ready? */ 3550 /* TODO: Check for elpg being ready? */
3556 ap_cmd.init.cmd_id = PMU_AP_CMD_ID_INIT; 3551 ap_cmd.init.cmd_id = PMU_AP_CMD_ID_INIT;
3557 ap_cmd.init.pg_sampling_period_us = 3552 ap_cmd.init.pg_sampling_period_us = g->pmu.aelpg_param[0];
3558 APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US;
3559 3553
3560 status = gk20a_pmu_ap_send_command(g, &ap_cmd, false); 3554 status = gk20a_pmu_ap_send_command(g, &ap_cmd, false);
3561 return status; 3555 return status;
3562} 3556}
3563 3557
3564static int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id) 3558int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id)
3565{ 3559{
3566 int status = 0; 3560 int status = 0;
3567 union pmu_ap_cmd ap_cmd; 3561 union pmu_ap_cmd ap_cmd;
3568 3562
3569 /* TODO: Probably check if ELPG is ready? */ 3563 /* TODO: Probably check if ELPG is ready? */
3570
3571 ap_cmd.init_and_enable_ctrl.cmd_id = PMU_AP_CMD_ID_INIT_AND_ENABLE_CTRL; 3564 ap_cmd.init_and_enable_ctrl.cmd_id = PMU_AP_CMD_ID_INIT_AND_ENABLE_CTRL;
3572 ap_cmd.init_and_enable_ctrl.ctrl_id = ctrl_id; 3565 ap_cmd.init_and_enable_ctrl.ctrl_id = ctrl_id;
3573 ap_cmd.init_and_enable_ctrl.params.min_idle_filter_us = 3566 ap_cmd.init_and_enable_ctrl.params.min_idle_filter_us =
3574 APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US; 3567 g->pmu.aelpg_param[1];
3575 ap_cmd.init_and_enable_ctrl.params.min_target_saving_us = 3568 ap_cmd.init_and_enable_ctrl.params.min_target_saving_us =
3576 APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US; 3569 g->pmu.aelpg_param[2];
3577 ap_cmd.init_and_enable_ctrl.params.power_break_even_us = 3570 ap_cmd.init_and_enable_ctrl.params.power_break_even_us =
3578 APCTRL_POWER_BREAKEVEN_DEFAULT_US; 3571 g->pmu.aelpg_param[3];
3579 ap_cmd.init_and_enable_ctrl.params.cycles_per_sample_max = 3572 ap_cmd.init_and_enable_ctrl.params.cycles_per_sample_max =
3580 APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT; 3573 g->pmu.aelpg_param[4];
3581 3574
3582 switch (ctrl_id) { 3575 switch (ctrl_id) {
3583 case PMU_AP_CTRL_ID_GRAPHICS: 3576 case PMU_AP_CTRL_ID_GRAPHICS:
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
index 5c8a3215..fec0a572 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
@@ -1066,6 +1066,7 @@ struct pmu_gk20a {
1066 bool perfmon_sampling_enabled; 1066 bool perfmon_sampling_enabled;
1067 u8 pmu_mode; /*Added for GM20b, and ACR*/ 1067 u8 pmu_mode; /*Added for GM20b, and ACR*/
1068 u32 falcon_id; 1068 u32 falcon_id;
1069 u32 aelpg_param[5];
1069}; 1070};
1070 1071
1071int gk20a_init_pmu_support(struct gk20a *g); 1072int gk20a_init_pmu_support(struct gk20a *g);
@@ -1109,4 +1110,9 @@ void pmu_seq_init(struct pmu_gk20a *pmu);
1109 1110
1110int gk20a_init_pmu(struct pmu_gk20a *pmu); 1111int gk20a_init_pmu(struct pmu_gk20a *pmu);
1111 1112
1113int gk20a_pmu_ap_send_command(struct gk20a *g,
1114 union pmu_ap_cmd *p_ap_cmd, bool b_block);
1115int gk20a_aelpg_init(struct gk20a *g);
1116int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id);
1117
1112#endif /*__PMU_GK20A_H__*/ 1118#endif /*__PMU_GK20A_H__*/