summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c')
-rw-r--r--drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c59
1 files changed, 44 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c
index cf18fd24..3fc216a1 100644
--- a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c
@@ -50,6 +50,8 @@
50 50
51/* Select every GP10B_FREQ_SELECT_STEP'th frequency from h/w table */ 51/* Select every GP10B_FREQ_SELECT_STEP'th frequency from h/w table */
52#define GP10B_FREQ_SELECT_STEP 8 52#define GP10B_FREQ_SELECT_STEP 8
53/* Allow limited set of frequencies to be available */
54#define GP10B_NUM_SUPPORTED_FREQS 15
53/* Max number of freq supported in h/w */ 55/* Max number of freq supported in h/w */
54#define GP10B_MAX_SUPPORTED_FREQS 120 56#define GP10B_MAX_SUPPORTED_FREQS 120
55static unsigned long 57static unsigned long
@@ -343,33 +345,60 @@ int gp10b_clk_get_freqs(struct device *dev,
343 struct gk20a *g = platform->g; 345 struct gk20a *g = platform->g;
344 unsigned long max_rate; 346 unsigned long max_rate;
345 unsigned long new_rate = 0, prev_rate = 0; 347 unsigned long new_rate = 0, prev_rate = 0;
346 int i = 0, freq_counter = 0; 348 int i, freq_counter = 0;
349 int sel_freq_cnt;
350 unsigned long loc_freq_table[GP10B_MAX_SUPPORTED_FREQS];
347 351
348 max_rate = clk_round_rate(platform->clk[0], (UINT_MAX - 1)); 352 max_rate = clk_round_rate(platform->clk[0], (UINT_MAX - 1));
349 353
350 /* 354 /*
351 * Walk the h/w frequency table and only select 355 * Walk the h/w frequency table and update the local table
352 * GP10B_FREQ_SELECT_STEP'th frequencies and
353 * add MAX freq to last
354 */ 356 */
355 for (; i < GP10B_MAX_SUPPORTED_FREQS; ++i) { 357 for (i = 0; i < GP10B_MAX_SUPPORTED_FREQS; ++i) {
356 prev_rate = new_rate; 358 prev_rate = new_rate;
357 new_rate = clk_round_rate(platform->clk[0], prev_rate + 1); 359 new_rate = clk_round_rate(platform->clk[0],
358 360 prev_rate + 1);
359 if (i % GP10B_FREQ_SELECT_STEP == 0 || 361 loc_freq_table[i] = new_rate;
360 new_rate == max_rate) { 362 if (new_rate == max_rate)
361 gp10b_freq_table[freq_counter++] = new_rate; 363 break;
364 }
365 freq_counter = i;
366 WARN_ON(freq_counter == GP10B_MAX_SUPPORTED_FREQS);
362 367
363 if (new_rate == max_rate) 368 /*
364 break; 369 * If the number of achievable frequencies is less than or
370 * equal to GP10B_NUM_SUPPORTED_FREQS, select all frequencies
371 * else, select one out of every 8 frequencies
372 */
373 if (freq_counter <= GP10B_NUM_SUPPORTED_FREQS) {
374 for (sel_freq_cnt = 0; sel_freq_cnt < freq_counter; ++sel_freq_cnt)
375 gp10b_freq_table[sel_freq_cnt] =
376 loc_freq_table[sel_freq_cnt];
377 } else {
378 /*
379 * Walk the h/w frequency table and only select
380 * GP10B_FREQ_SELECT_STEP'th frequencies and
381 * add MAX freq to last
382 */
383 sel_freq_cnt = 0;
384 for (i = 0; i < GP10B_MAX_SUPPORTED_FREQS; ++i) {
385 new_rate = loc_freq_table[i];
386
387 if (i % GP10B_FREQ_SELECT_STEP == 0 ||
388 new_rate == max_rate) {
389 gp10b_freq_table[sel_freq_cnt++] =
390 new_rate;
391
392 if (new_rate == max_rate)
393 break;
394 }
365 } 395 }
396 WARN_ON(sel_freq_cnt == GP10B_MAX_SUPPORTED_FREQS);
366 } 397 }
367 398
368 WARN_ON(i == GP10B_MAX_SUPPORTED_FREQS);
369
370 /* Fill freq table */ 399 /* Fill freq table */
371 *freqs = gp10b_freq_table; 400 *freqs = gp10b_freq_table;
372 *num_freqs = freq_counter; 401 *num_freqs = sel_freq_cnt;
373 402
374 nvgpu_log_info(g, "min rate: %ld max rate: %ld num_of_freq %d\n", 403 nvgpu_log_info(g, "min rate: %ld max rate: %ld num_of_freq %d\n",
375 gp10b_freq_table[0], max_rate, *num_freqs); 404 gp10b_freq_table[0], max_rate, *num_freqs);