From fc27aab523fc8bdec2c69b54e5cd171751c07294 Mon Sep 17 00:00:00 2001 From: Seshendra Gadagottu Date: Wed, 27 Oct 2021 04:38:24 -0700 Subject: [PATCH] gpu: nvgpu: ga10b: update clock operations ga10b can have 2 GPCs and each GPC is clocked with separate gpc clk. Added ga10b specific set_rate/get_rate operations for gpcclks considering GPC floor-sweeping info. Bug 3315239 Change-Id: I4e2156b4e06a1580a60d832e0d3296ed3dc17887 Signed-off-by: Seshendra Gadagottu Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2617441 Reviewed-by: Tejal Kudav Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: Tejal Kudav Tested-by: mobile promotions --- arch/nvgpu-linux.yaml | 3 +- drivers/gpu/nvgpu/Makefile | 3 +- drivers/gpu/nvgpu/os/linux/clk.c | 22 ++++- drivers/gpu/nvgpu/os/linux/clk_ga10b.c | 111 +++++++++++++++++++++++++ drivers/gpu/nvgpu/os/linux/clk_ga10b.h | 26 ++++++ 5 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/nvgpu/os/linux/clk_ga10b.c create mode 100644 drivers/gpu/nvgpu/os/linux/clk_ga10b.h diff --git a/arch/nvgpu-linux.yaml b/arch/nvgpu-linux.yaml index 03d93b9c2..b7e0829c2 100644 --- a/arch/nvgpu-linux.yaml +++ b/arch/nvgpu-linux.yaml @@ -20,7 +20,8 @@ vpr: sources: [ os/linux/vpr.c ] clk: - sources: [ os/linux/clk.c, os/linux/clk.h ] + sources: [ os/linux/clk.c, os/linux/clk.h, + os/linux/clk_ga10b.c, os/linux/clk_ga10b.h ] cde: sources: [ os/linux/cde.c, os/linux/cde.h, diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 15feb926b..eadfbec5f 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -558,7 +558,8 @@ nvgpu-$(CONFIG_NVGPU_GR_VIRTUALIZATION) += \ endif nvgpu-$(CONFIG_COMMON_CLK) += \ - os/linux/clk.o + os/linux/clk.o \ + os/linux/clk_ga10b.o nvgpu-$(CONFIG_GK20A_DEVFREQ) += \ os/linux/scale.o diff --git a/drivers/gpu/nvgpu/os/linux/clk.c b/drivers/gpu/nvgpu/os/linux/clk.c index 4347e6c22..6370a9cb5 100644 --- a/drivers/gpu/nvgpu/os/linux/clk.c +++ b/drivers/gpu/nvgpu/os/linux/clk.c @@ -1,7 +1,7 @@ /* * Linux clock support * - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2021, 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, @@ -29,11 +29,15 @@ #include #include "clk.h" +#include "clk_ga10b.h" #include "os_linux.h" #include "platform_gk20a.h" #include #include +#if defined(CONFIG_NVGPU_HAL_NON_FUSA) && defined(CONFIG_NVGPU_NEXT) +#include +#endif #define HZ_TO_MHZ(x) ((x) / 1000000) @@ -292,8 +296,20 @@ static void nvgpu_linux_disable_unprepare(struct clk_gk20a *clk) 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; + struct device *dev = dev_from_gk20a(g); + struct gk20a_platform *platform = dev_get_drvdata(dev); + + if ((platform->platform_chip_id == TEGRA_234) +#if defined(CONFIG_NVGPU_HAL_NON_FUSA) && defined(CONFIG_NVGPU_NEXT) + || (platform->platform_chip_id == TEGRA_239) +#endif + ){ + g->ops.clk.get_rate = nvgpu_ga10b_linux_clk_get_rate; + g->ops.clk.set_rate = nvgpu_ga10b_linux_clk_set_rate; + } else { + g->ops.clk.get_rate = nvgpu_linux_clk_get_rate; + g->ops.clk.set_rate = nvgpu_linux_clk_set_rate; + } g->ops.clk.get_fmax_at_vmin_safe = nvgpu_linux_get_fmax_at_vmin_safe; g->ops.clk.get_ref_clock_rate = nvgpu_linux_get_ref_clock_rate; g->ops.clk.predict_mv_at_hz_cur_tfloor = nvgpu_linux_predict_mv_at_hz_cur_tfloor; diff --git a/drivers/gpu/nvgpu/os/linux/clk_ga10b.c b/drivers/gpu/nvgpu/os/linux/clk_ga10b.c new file mode 100644 index 000000000..d110785eb --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/clk_ga10b.c @@ -0,0 +1,111 @@ +/* + * Linux clock support for ga10b + * + * Copyright (c) 2017-2021, 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 "clk.h" +#include "os_linux.h" +#include "platform_gk20a.h" + +#include +#include +#include +#include +#include + +/* + * GA10B clock list: + * platform->clk[0]- sysclk + * For GPU Full config: + * platform->clk[1] - gpc0 clk + * platform->clk[2] - gpc1 clk + * platform->clk[3] - fuse clk + * For GPU GPC Floor-swept config: + * platform->clk[1] - Active gpc(gpc0/gpc1) clk + * platform->clk[2] - fuse clk + */ + +/* + * GPU clock policy for ga10b: + * All sys, gpc0 and gpc1 clk are at same rate. + * So, for clock set_rate, change all clocks for + * any clock rate change request. + */ + +/* + * PWRCLK is used for pmu runs at fixed rate 204MHZ in ga10b + * PWRCLK is enabled once gpu out of reset. CCF is not + * supporting any clock set/get calls for PWRCLK. To support + * legacy code, nvgpu driver only supporting clk_get_rate by + * returning fixed 204MHz rate + */ +#define NVGPU_GA10B_PWRCLK_RATE 204000000UL; + +unsigned long nvgpu_ga10b_linux_clk_get_rate( + struct gk20a *g, u32 api_domain) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); + unsigned long ret; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_SYSCLK: + case CTRL_CLK_DOMAIN_GPCCLK: + ret = clk_get_rate(platform->clk[0]); + break; + case CTRL_CLK_DOMAIN_PWRCLK: + /* power domain is at fixed clock */ + ret = NVGPU_GA10B_PWRCLK_RATE; + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = 0; + break; + } + + return ret; +} + +int nvgpu_ga10b_linux_clk_set_rate(struct gk20a *g, + u32 api_domain, unsigned long rate) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); + struct nvgpu_gr_config *gr_config = nvgpu_gr_get_config_ptr(g); + u32 gpc_count = nvgpu_gr_config_get_gpc_count(gr_config); + int ret; + + switch (api_domain) { + case CTRL_CLK_DOMAIN_GPCCLK: + case CTRL_CLK_DOMAIN_SYSCLK: + ret = clk_set_rate(platform->clk[0], rate); + ret = clk_set_rate(platform->clk[1], rate); + /* Set second gpcclk for full-config */ + if (gpc_count == 2U) + ret = clk_set_rate(platform->clk[2], rate); + break; + case CTRL_CLK_DOMAIN_PWRCLK: + nvgpu_err(g, "unsupported operation: %u", api_domain); + ret = -EINVAL; + break; + default: + nvgpu_err(g, "unknown clock: %u", api_domain); + ret = -EINVAL; + break; + } + + return ret; +} diff --git a/drivers/gpu/nvgpu/os/linux/clk_ga10b.h b/drivers/gpu/nvgpu/os/linux/clk_ga10b.h new file mode 100644 index 000000000..6d8cde551 --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/clk_ga10b.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021, 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_GA10B_H + +struct gk20a; + +unsigned long nvgpu_ga10b_linux_clk_get_rate( + struct gk20a *g, u32 api_domain); +int nvgpu_ga10b_linux_clk_set_rate(struct gk20a *g, + u32 api_domain, unsigned long rate); + +#endif