From e9a6d179a42e7bdd6bb4876fb14f4ff7ab0df852 Mon Sep 17 00:00:00 2001 From: Arun Kannan Date: Mon, 5 Mar 2018 14:32:08 -0800 Subject: gpu: nvgpu: cache gpu clk rate Cache the rate used in clk_set_rate(). Return that cached rate on clk_get_rate(), don't read from hardware. This cached rate is used to avoid duplicate requests to clk_set_rate(). Motivation is to support multiple governors for gpu clk. Reading clock from hardware is unreliable in multi-governor situation. Relying on hardware clock value could mislead the kernel gpu governor in its scaling calculations. Bug 2051688 Change-Id: I43fc056eea6f69fe0889c45640fcb892b658071c Signed-off-by: Arun Kannan (cherry picked from commit 7f819a9ba707e6e905168b00b0f3bf6348e86188) Reviewed-on: https://git-master.nvidia.com/r/1662759 Reviewed-on: https://git-master.nvidia.com/r/1668919 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/clk.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/nvgpu/common/linux/clk.c') diff --git a/drivers/gpu/nvgpu/common/linux/clk.c b/drivers/gpu/nvgpu/common/linux/clk.c index ea5b023d..8bffc07b 100644 --- a/drivers/gpu/nvgpu/common/linux/clk.c +++ b/drivers/gpu/nvgpu/common/linux/clk.c @@ -1,7 +1,7 @@ /* * Linux clock support * - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2018, 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, @@ -34,9 +34,13 @@ static unsigned long nvgpu_linux_clk_get_rate(struct gk20a *g, u32 api_domain) switch (api_domain) { case CTRL_CLK_DOMAIN_GPCCLK: if (g->clk.tegra_clk) - ret = clk_get_rate(g->clk.tegra_clk); + ret = g->clk.cached_rate ? + g->clk.cached_rate : + clk_get_rate(g->clk.tegra_clk); else - ret = clk_get_rate(platform->clk[0]); + ret = platform->cached_rate ? + platform->cached_rate : + clk_get_rate(platform->clk[0]); break; case CTRL_CLK_DOMAIN_PWRCLK: ret = clk_get_rate(platform->clk[1]); @@ -58,10 +62,15 @@ static int nvgpu_linux_clk_set_rate(struct gk20a *g, switch (api_domain) { case CTRL_CLK_DOMAIN_GPCCLK: - if (g->clk.tegra_clk) + if (g->clk.tegra_clk) { ret = clk_set_rate(g->clk.tegra_clk, rate); - else + if (!ret) + g->clk.cached_rate = rate; + } else { ret = clk_set_rate(platform->clk[0], rate); + if (!ret) + platform->cached_rate = rate; + } break; case CTRL_CLK_DOMAIN_PWRCLK: ret = clk_set_rate(platform->clk[1], rate); -- cgit v1.2.2