From 589d6385b19a357cf566b75ded9355f9b8053ad7 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Thu, 2 Feb 2017 13:24:21 -0800 Subject: gpu: nvgpu: Implement get_rate/set_rate as GPU op Move clock APIs from gk20a_platform to gpu_ops. At the same time allow use of internal get_rate/set_rate for querying both GPCCLK and PWRCLK on iGPU. At the same time we can replace calls to clk framework with the new HAL and drop direct dependency to clk framework. gp10b ops were replaced as a whole at HAL initialization. That replaces anything set in platform probe stage, so reduce that to touch only clock gating regs. Change-Id: Iaf219b1f000d362dbf397d45832f52d25463b31c Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/1300113 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/tegra/linux/clk.c | 76 ++++++++++++++++++++++ drivers/gpu/nvgpu/tegra/linux/clk.h | 22 +++++++ .../gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c | 24 +------ .../gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c | 20 +----- 4 files changed, 104 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/nvgpu/tegra/linux/clk.c create mode 100644 drivers/gpu/nvgpu/tegra/linux/clk.h (limited to 'drivers/gpu/nvgpu/tegra/linux') diff --git a/drivers/gpu/nvgpu/tegra/linux/clk.c b/drivers/gpu/nvgpu/tegra/linux/clk.c new file mode 100644 index 00000000..3982054c --- /dev/null +++ b/drivers/gpu/nvgpu/tegra/linux/clk.c @@ -0,0 +1,76 @@ +/* + * Linux clock support + * + * Copyright (c) 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "gk20a/gk20a.h" + +static unsigned long nvgpu_linux_clk_get_rate(struct gk20a *g, u32 api_domain) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + unsigned long ret; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + if (g->clk.tegra_clk) + ret = clk_get_rate(g->clk.tegra_clk); + else + ret = clk_get_rate(platform->clk[0]); + break; + case CTRL_CLK_DOMAIN_PWRCLK: + ret = clk_get_rate(platform->clk[1]); + break; + default: + gk20a_err(g->dev, "unknown clock: %u", api_domain); + ret = 0; + break; + } + + return ret; +} + +static int nvgpu_linux_clk_set_rate(struct gk20a *g, + u32 api_domain, unsigned long rate) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + int ret; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + if (g->clk.tegra_clk) + ret = clk_set_rate(g->clk.tegra_clk, rate); + else + ret = clk_set_rate(platform->clk[0], rate); + break; + case CTRL_CLK_DOMAIN_PWRCLK: + ret = clk_set_rate(platform->clk[1], rate); + break; + default: + gk20a_err(g->dev, "unknown clock: %u", api_domain); + ret = -EINVAL; + break; + } + + return ret; +} + +void nvgpu_linux_init_clk_support(struct gk20a *g) +{ + g->ops.clk.get_rate = nvgpu_linux_clk_get_rate; + g->ops.clk.set_rate = nvgpu_linux_clk_set_rate; +} diff --git a/drivers/gpu/nvgpu/tegra/linux/clk.h b/drivers/gpu/nvgpu/tegra/linux/clk.h new file mode 100644 index 00000000..614a7fd7 --- /dev/null +++ b/drivers/gpu/nvgpu/tegra/linux/clk.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 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, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NVGPU_COMMON_LINUX_CLK_H + +struct gk20a; +void nvgpu_linux_init_clk_support(struct gk20a *g); + +#endif diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c index 56ba1ecd..1b40702a 100644 --- a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c @@ -49,6 +49,8 @@ #include "gk20a/gk20a_scale.h" #include "gm20b/clk_gm20b.h" +#include "clk.h" + #define TEGRA_GK20A_BW_PER_FREQ 32 #define TEGRA_GM20B_BW_PER_FREQ 64 #define TEGRA_DDR3_BW_PER_FREQ 16 @@ -938,6 +940,7 @@ static int gk20a_tegra_probe(struct device *dev) platform->g->mm.vidmem_is_vidmem = platform->vidmem_is_vidmem; gk20a_tegra_get_clocks(dev); + nvgpu_linux_init_clk_support(platform->g); if (platform->clk_register) { ret = platform->clk_register(platform->g); @@ -975,15 +978,6 @@ static int gk20a_tegra_suspend(struct device *dev) } #if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_COMMON_CLK) -static unsigned long gk20a_get_clk_rate(struct device *dev) -{ - struct gk20a_platform *platform = gk20a_get_platform(dev); - struct gk20a *g = platform->g; - - return gk20a_clk_get_rate(g); - -} - static long gk20a_round_clk_rate(struct device *dev, unsigned long rate) { struct gk20a_platform *platform = gk20a_get_platform(dev); @@ -992,14 +986,6 @@ static long gk20a_round_clk_rate(struct device *dev, unsigned long rate) return gk20a_clk_round_rate(g, rate); } -static int gk20a_set_clk_rate(struct device *dev, unsigned long rate) -{ - struct gk20a_platform *platform = gk20a_get_platform(dev); - struct gk20a *g = platform->g; - - return gk20a_clk_set_rate(g, rate); -} - static int gk20a_clk_get_freqs(struct device *dev, unsigned long **freqs, int *num_freqs) { @@ -1056,9 +1042,7 @@ struct gk20a_platform gk20a_tegra_platform = { .reset_deassert = gk20a_tegra_reset_deassert, #ifdef CONFIG_TEGRA_CLK_FRAMEWORK - .clk_get_rate = gk20a_get_clk_rate, .clk_round_rate = gk20a_round_clk_rate, - .clk_set_rate = gk20a_set_clk_rate, .get_clk_freqs = gk20a_clk_get_freqs, #endif @@ -1124,9 +1108,7 @@ struct gk20a_platform gm20b_tegra_platform = { #endif #if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_COMMON_CLK) - .clk_get_rate = gk20a_get_clk_rate, .clk_round_rate = gk20a_round_clk_rate, - .clk_set_rate = gk20a_set_clk_rate, .get_clk_freqs = gk20a_clk_get_freqs, #endif diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c index f0c3640a..27db9c12 100644 --- a/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c +++ b/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c @@ -29,6 +29,8 @@ #include +#include "clk.h" + #include "gk20a/platform_gk20a.h" #include "gk20a/gk20a.h" #include "gk20a/gk20a_scale.h" @@ -173,6 +175,7 @@ static int gp10b_tegra_probe(struct device *dev) platform->g->mm.vidmem_is_vidmem = platform->vidmem_is_vidmem; gp10b_tegra_get_clocks(dev); + nvgpu_linux_init_clk_support(platform->g); return 0; } @@ -329,14 +332,6 @@ static void gp10b_tegra_postscale(struct device *pdev, gk20a_dbg_fn("done"); } -static unsigned long gp10b_get_clk_rate(struct device *dev) -{ - struct gk20a_platform *platform = gk20a_get_platform(dev); - - return clk_get_rate(platform->clk[0]); - -} - static long gp10b_round_clk_rate(struct device *dev, unsigned long rate) { struct gk20a *g = get_gk20a(dev); @@ -352,13 +347,6 @@ static long gp10b_round_clk_rate(struct device *dev, unsigned long rate) return freq_table[max_states - 1]; } -static int gp10b_set_clk_rate(struct device *dev, unsigned long rate) -{ - struct gk20a_platform *platform = gk20a_get_platform(dev); - - return clk_set_rate(platform->clk[0], rate); -} - static int gp10b_clk_get_freqs(struct device *dev, unsigned long **freqs, int *num_freqs) { @@ -440,9 +428,7 @@ struct gk20a_platform gp10b_tegra_platform = { .has_ce = true, - .clk_get_rate = gp10b_get_clk_rate, .clk_round_rate = gp10b_round_clk_rate, - .clk_set_rate = gp10b_set_clk_rate, .get_clk_freqs = gp10b_clk_get_freqs, /* frequency scaling configuration */ -- cgit v1.2.2