diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a_scale.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_scale.c | 66 |
1 files changed, 53 insertions, 13 deletions
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 | ||