From b5c6aebe7a090a8888d7cd6607d58c061757cb78 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Fri, 21 Oct 2016 14:53:44 +0530 Subject: gpu: nvgpu: select N'th freq from all available frequencies We right now get min and max frequencies, and then interpolate rest of the frequencies. With this approach, we do not select exact frequencies as supported by h/w Fix this so that we query all supported frequencies using clk_round_rate() and then select every N'th frequency to keep number of frequencies under limit Use GP10B_FREQ_SELECT_STEP (currently set to 8) to configure frequency selection step Raise GP10B_MAX_SUPPORTED_FREQS to 200 since h/w supported frequencies could be in that range Bug 1827281 Change-Id: Id8678d7a0280a249e4affbba084ff2e33b6694e6 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/1280629 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c | 47 +++++++++++++++++++------- 1 file changed, 34 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c') diff --git a/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c index 8cf6d5e8..5e5c7703 100644 --- a/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c +++ b/drivers/gpu/nvgpu/gp10b/platform_gp10b_tegra.c @@ -1,7 +1,7 @@ /* * GP10B Tegra Platform Interface * - * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -35,8 +35,12 @@ #include "gp10b_sysfs.h" #include -#define GP10B_MAX_SUPPORTED_FREQS 11 -static unsigned long gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS]; +/* Select every GP10B_FREQ_SELECT_STEP'th frequency from h/w table */ +#define GP10B_FREQ_SELECT_STEP 8 +/* Max number of freq supported in h/w */ +#define GP10B_MAX_SUPPORTED_FREQS 120 +static unsigned long +gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS / GP10B_FREQ_SELECT_STEP]; #define TEGRA_GP10B_BW_PER_FREQ 64 #define TEGRA_DDR4_BW_PER_FREQ 16 @@ -340,22 +344,39 @@ static int gp10b_clk_get_freqs(struct device *dev, unsigned long **freqs, int *num_freqs) { struct gk20a_platform *platform = gk20a_get_platform(dev); - unsigned long min_rate, max_rate, freq_step, rate; - int i; + unsigned long max_rate; + unsigned long new_rate = 0, prev_rate = 0; + int i = 0, freq_counter = 0; - min_rate = clk_round_rate(platform->clk[0], 0); max_rate = clk_round_rate(platform->clk[0], (UINT_MAX - 1)); - freq_step = (max_rate - min_rate)/(GP10B_MAX_SUPPORTED_FREQS - 1); - gk20a_dbg_info("min rate: %ld max rate: %ld freq step %ld\n", - min_rate, max_rate, freq_step); - for (i = 0; i < GP10B_MAX_SUPPORTED_FREQS; i++) { - rate = min_rate + i * freq_step; - gp10b_freq_table[i] = clk_round_rate(platform->clk[0], rate); + /* + * Walk the h/w frequency table and only select + * GP10B_FREQ_SELECT_STEP'th frequencies and + * add MAX freq to last + */ + for (; i < GP10B_MAX_SUPPORTED_FREQS; ++i) { + prev_rate = new_rate; + new_rate = clk_round_rate(platform->clk[0], prev_rate + 1); + + if (i % GP10B_FREQ_SELECT_STEP == 0 || + new_rate == max_rate) { + gp10b_freq_table[freq_counter++] = new_rate; + + if (new_rate == max_rate) + break; + } } + + WARN_ON(i == GP10B_MAX_SUPPORTED_FREQS); + /* Fill freq table */ *freqs = gp10b_freq_table; - *num_freqs = GP10B_MAX_SUPPORTED_FREQS; + *num_freqs = freq_counter; + + gk20a_dbg_info("min rate: %ld max rate: %ld num_of_freq %d\n", + gp10b_freq_table[0], max_rate, *num_freqs); + return 0; } -- cgit v1.2.2