diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_scale.c | 66 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_scale.h | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/platform_gk20a.h | 9 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c | 4 |
5 files changed, 69 insertions, 19 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 997da125..9acaa007 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -815,6 +815,8 @@ struct gk20a { | |||
815 | wait_queue_head_t sw_irq_nonstall_last_handled_wq; | 815 | wait_queue_head_t sw_irq_nonstall_last_handled_wq; |
816 | 816 | ||
817 | struct devfreq *devfreq; | 817 | struct devfreq *devfreq; |
818 | u32 devfreq_max_freq; | ||
819 | u32 devfreq_min_freq; | ||
818 | 820 | ||
819 | struct gk20a_scale_profile *scale_profile; | 821 | struct gk20a_scale_profile *scale_profile; |
820 | 822 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_scale.c b/drivers/gpu/nvgpu/gk20a/gk20a_scale.c index 6d60d899..eeabd919 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_scale.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_scale.c | |||
@@ -41,8 +41,44 @@ | |||
41 | * has changed. The function calls postscaling callback if it is defined. | 41 | * has changed. The function calls postscaling callback if it is defined. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | static int gk20a_scale_qos_notify(struct notifier_block *nb, | 44 | #if defined(CONFIG_COMMON_CLK) |
45 | unsigned long n, void *p) | 45 | int gk20a_scale_qos_notify(struct notifier_block *nb, |
46 | unsigned long n, void *p) | ||
47 | { | ||
48 | struct gk20a_scale_profile *profile = | ||
49 | container_of(nb, struct gk20a_scale_profile, | ||
50 | qos_notify_block); | ||
51 | struct gk20a *g = get_gk20a(profile->dev); | ||
52 | struct devfreq *devfreq = g->devfreq; | ||
53 | s32 min_qos_freq, max_qos_freq; | ||
54 | |||
55 | if (!devfreq) | ||
56 | return NOTIFY_OK; | ||
57 | |||
58 | /* check for pm_qos min and max frequency requirement */ | ||
59 | min_qos_freq = pm_qos_read_min_bound(PM_QOS_GPU_FREQ_BOUNDS) * 1000; | ||
60 | max_qos_freq = pm_qos_read_max_bound(PM_QOS_GPU_FREQ_BOUNDS) * 1000; | ||
61 | |||
62 | mutex_lock(&devfreq->lock); | ||
63 | |||
64 | devfreq->min_freq = max_t(u32, g->devfreq_min_freq, min_qos_freq); | ||
65 | devfreq->max_freq = min_t(u32, g->devfreq_max_freq, max_qos_freq); | ||
66 | |||
67 | WARN_ON(devfreq->min_freq > devfreq->max_freq); | ||
68 | |||
69 | /* | ||
70 | * update_devfreq() will adjust the current (or newly estimated) | ||
71 | * frequency based on devfreq->min_freq/max_freq | ||
72 | */ | ||
73 | update_devfreq(devfreq); | ||
74 | |||
75 | mutex_unlock(&devfreq->lock); | ||
76 | |||
77 | return NOTIFY_OK; | ||
78 | } | ||
79 | #else | ||
80 | int gk20a_scale_qos_notify(struct notifier_block *nb, | ||
81 | unsigned long n, void *p) | ||
46 | { | 82 | { |
47 | struct gk20a_scale_profile *profile = | 83 | struct gk20a_scale_profile *profile = |
48 | container_of(nb, struct gk20a_scale_profile, | 84 | container_of(nb, struct gk20a_scale_profile, |
@@ -57,7 +93,7 @@ static int gk20a_scale_qos_notify(struct notifier_block *nb, | |||
57 | /* get the frequency requirement. if devfreq is enabled, check if it | 93 | /* get the frequency requirement. if devfreq is enabled, check if it |
58 | * has higher demand than qos */ | 94 | * has higher demand than qos */ |
59 | freq = platform->clk_round_rate(profile->dev, | 95 | freq = platform->clk_round_rate(profile->dev, |
60 | pm_qos_request(platform->qos_id)); | 96 | (u32)pm_qos_read_min_bound(PM_QOS_GPU_FREQ_BOUNDS)); |
61 | if (g->devfreq) | 97 | if (g->devfreq) |
62 | freq = max(g->devfreq->previous_freq, freq); | 98 | freq = max(g->devfreq->previous_freq, freq); |
63 | 99 | ||
@@ -68,6 +104,7 @@ static int gk20a_scale_qos_notify(struct notifier_block *nb, | |||
68 | 104 | ||
69 | return NOTIFY_OK; | 105 | return NOTIFY_OK; |
70 | } | 106 | } |
107 | #endif | ||
71 | 108 | ||
72 | /* | 109 | /* |
73 | * gk20a_scale_make_freq_table(profile) | 110 | * gk20a_scale_make_freq_table(profile) |
@@ -311,16 +348,19 @@ void gk20a_scale_init(struct device *dev) | |||
311 | devfreq = NULL; | 348 | devfreq = NULL; |
312 | 349 | ||
313 | g->devfreq = devfreq; | 350 | g->devfreq = devfreq; |
351 | g->devfreq_max_freq = devfreq->max_freq; | ||
352 | g->devfreq_min_freq = devfreq->min_freq; | ||
314 | } | 353 | } |
315 | 354 | ||
316 | /* Should we register QoS callback for this device? */ | 355 | /* Should we register QoS callback for this device? */ |
317 | if (platform->qos_id < PM_QOS_NUM_CLASSES && | 356 | if (platform->qos_notify) { |
318 | platform->qos_id != PM_QOS_RESERVED && | ||
319 | platform->postscale) { | ||
320 | profile->qos_notify_block.notifier_call = | 357 | profile->qos_notify_block.notifier_call = |
321 | &gk20a_scale_qos_notify; | 358 | platform->qos_notify; |
322 | pm_qos_add_notifier(platform->qos_id, | 359 | |
323 | &profile->qos_notify_block); | 360 | pm_qos_add_min_notifier(PM_QOS_GPU_FREQ_BOUNDS, |
361 | &profile->qos_notify_block); | ||
362 | pm_qos_add_max_notifier(PM_QOS_GPU_FREQ_BOUNDS, | ||
363 | &profile->qos_notify_block); | ||
324 | } | 364 | } |
325 | 365 | ||
326 | return; | 366 | return; |
@@ -335,10 +375,10 @@ void gk20a_scale_exit(struct device *dev) | |||
335 | struct gk20a *g = platform->g; | 375 | struct gk20a *g = platform->g; |
336 | int err; | 376 | int err; |
337 | 377 | ||
338 | if (platform->qos_id < PM_QOS_NUM_CLASSES && | 378 | if (platform->qos_notify) { |
339 | platform->qos_id != PM_QOS_RESERVED && | 379 | pm_qos_remove_min_notifier(PM_QOS_GPU_FREQ_BOUNDS, |
340 | platform->postscale) { | 380 | &g->scale_profile->qos_notify_block); |
341 | pm_qos_remove_notifier(platform->qos_id, | 381 | pm_qos_remove_max_notifier(PM_QOS_GPU_FREQ_BOUNDS, |
342 | &g->scale_profile->qos_notify_block); | 382 | &g->scale_profile->qos_notify_block); |
343 | } | 383 | } |
344 | 384 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_scale.h b/drivers/gpu/nvgpu/gk20a/gk20a_scale.h index 5c8618eb..025c2070 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_scale.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a_scale.h | |||
@@ -47,11 +47,18 @@ void gk20a_scale_notify_idle(struct device *); | |||
47 | 47 | ||
48 | void gk20a_scale_suspend(struct device *); | 48 | void gk20a_scale_suspend(struct device *); |
49 | void gk20a_scale_resume(struct device *); | 49 | void gk20a_scale_resume(struct device *); |
50 | int gk20a_scale_qos_notify(struct notifier_block *nb, | ||
51 | unsigned long n, void *p); | ||
50 | #else | 52 | #else |
51 | static inline void gk20a_scale_notify_busy(struct device *dev) {} | 53 | static inline void gk20a_scale_notify_busy(struct device *dev) {} |
52 | static inline void gk20a_scale_notify_idle(struct device *dev) {} | 54 | static inline void gk20a_scale_notify_idle(struct device *dev) {} |
53 | static inline void gk20a_scale_suspend(struct device *dev) {} | 55 | static inline void gk20a_scale_suspend(struct device *dev) {} |
54 | static inline void gk20a_scale_resume(struct device *dev) {} | 56 | static inline void gk20a_scale_resume(struct device *dev) {} |
57 | static inline int gk20a_scale_qos_notify(struct notifier_block *nb, | ||
58 | unsigned long n, void *p) | ||
59 | { | ||
60 | return -ENOSYS; | ||
61 | } | ||
55 | #endif | 62 | #endif |
56 | 63 | ||
57 | #endif | 64 | #endif |
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h index 66d97915..a753201b 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h | |||
@@ -181,10 +181,11 @@ struct gk20a_platform { | |||
181 | * this governor to be used in scaling */ | 181 | * this governor to be used in scaling */ |
182 | const char *devfreq_governor; | 182 | const char *devfreq_governor; |
183 | 183 | ||
184 | /* Quality of service id. If this is set, the scaling routines | 184 | /* Quality of service notifier callback. If this is set, the scaling |
185 | * will register a callback to id. Each time we receive a new value, | 185 | * routines will register a callback to Qos. Each time we receive |
186 | * the postscale callback gets called. */ | 186 | * a new value, this callback gets called. */ |
187 | int qos_id; | 187 | int (*qos_notify)(struct notifier_block *nb, |
188 | unsigned long n, void *p); | ||
188 | 189 | ||
189 | /* Called as part of debug dump. If the gpu gets hung, this function | 190 | /* Called as part of debug dump. If the gpu gets hung, this function |
190 | * is responsible for delivering all necessary debug data of other | 191 | * is responsible for delivering all necessary debug data of other |
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c index 618b1716..b8f70ab3 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c | |||
@@ -896,7 +896,7 @@ struct gk20a_platform gk20a_tegra_platform = { | |||
896 | .prescale = gk20a_tegra_prescale, | 896 | .prescale = gk20a_tegra_prescale, |
897 | .postscale = gk20a_tegra_postscale, | 897 | .postscale = gk20a_tegra_postscale, |
898 | .devfreq_governor = "nvhost_podgov", | 898 | .devfreq_governor = "nvhost_podgov", |
899 | .qos_id = PM_QOS_GPU_FREQ_MIN, | 899 | .qos_notify = gk20a_scale_qos_notify, |
900 | 900 | ||
901 | .secure_alloc = gk20a_tegra_secure_alloc, | 901 | .secure_alloc = gk20a_tegra_secure_alloc, |
902 | .secure_page_alloc = gk20a_tegra_secure_page_alloc, | 902 | .secure_page_alloc = gk20a_tegra_secure_page_alloc, |
@@ -956,7 +956,7 @@ struct gk20a_platform gm20b_tegra_platform = { | |||
956 | .prescale = gk20a_tegra_prescale, | 956 | .prescale = gk20a_tegra_prescale, |
957 | .postscale = gk20a_tegra_postscale, | 957 | .postscale = gk20a_tegra_postscale, |
958 | .devfreq_governor = "nvhost_podgov", | 958 | .devfreq_governor = "nvhost_podgov", |
959 | .qos_id = PM_QOS_GPU_FREQ_MIN, | 959 | .qos_notify = gk20a_scale_qos_notify, |
960 | 960 | ||
961 | .secure_alloc = gk20a_tegra_secure_alloc, | 961 | .secure_alloc = gk20a_tegra_secure_alloc, |
962 | .secure_page_alloc = gk20a_tegra_secure_page_alloc, | 962 | .secure_page_alloc = gk20a_tegra_secure_page_alloc, |