From 004a1880ed80f3b384cf3d0d37e0a58eff29fcaf Mon Sep 17 00:00:00 2001 From: Seshendra Gadagottu Date: Fri, 23 Oct 2015 12:02:55 -0700 Subject: gpu: nvgpu: update thermal programming Add required fileds and values for thermal slow-down settings in thermal header file and implemented chip specific thermal register programming Reviewed-on: http://git-master/r/822199 (cherry picked from commit 9e8a745b8295af002b9780c83caa8dc7b22cc737) Change-Id: I016b18ed230fa6c104eada2e166ccd1a5f2ace36 Signed-off-by: Seshendra Gadagottu Reviewed-on: http://git-master/r/823012 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/Makefile | 3 +- drivers/gpu/nvgpu/gk20a/gk20a.h | 3 ++ drivers/gpu/nvgpu/gk20a/hal_gk20a.c | 2 + drivers/gpu/nvgpu/gk20a/hw_therm_gk20a.h | 48 +++++++++++++++++++++ drivers/gpu/nvgpu/gk20a/therm_gk20a.c | 25 ++++++++--- drivers/gpu/nvgpu/gk20a/therm_gk20a.h | 11 ++--- drivers/gpu/nvgpu/gm20b/hal_gm20b.c | 2 + drivers/gpu/nvgpu/gm20b/hw_therm_gm20b.h | 36 ++++++++++++++++ drivers/gpu/nvgpu/gm20b/therm_gm20b.c | 72 ++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gm20b/therm_gm20b.h | 21 ++++++++++ 10 files changed, 208 insertions(+), 15 deletions(-) create mode 100644 drivers/gpu/nvgpu/gm20b/therm_gm20b.c create mode 100644 drivers/gpu/nvgpu/gm20b/therm_gm20b.h (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index ee2117b9..966c5eea 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -62,7 +62,8 @@ nvgpu-y := \ gm20b/regops_gm20b.o \ gm20b/mc_gm20b.o \ gm20b/debug_gm20b.o \ - gm20b/cde_gm20b.o + gm20b/cde_gm20b.o \ + gm20b/therm_gm20b.o nvgpu-$(CONFIG_TEGRA_GK20A) += gk20a/platform_gk20a_tegra.o nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 1cf90fbf..328bb73b 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -387,6 +387,9 @@ struct gpu_ops { u64 (*get_iova_addr)(struct gk20a *g, struct scatterlist *sgl, u32 flags); } mm; + struct { + int (*init_therm_setup_hw)(struct gk20a *g); + } therm; struct { int (*prepare_ucode)(struct gk20a *g); int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c index b8268e1f..a9ad970a 100644 --- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c @@ -27,6 +27,7 @@ #include "pmu_gk20a.h" #include "clk_gk20a.h" #include "regops_gk20a.h" +#include "therm_gk20a.h" static struct gpu_ops gk20a_ops = { .clock_gating = { @@ -65,6 +66,7 @@ int gk20a_init_hal(struct gk20a *g) gk20a_init_clk_ops(gops); gk20a_init_regops(gops); gk20a_init_debug_ops(gops); + gk20a_init_therm_ops(gops); gops->name = "gk20a"; c->twod_class = FERMI_TWOD_A; diff --git a/drivers/gpu/nvgpu/gk20a/hw_therm_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_therm_gk20a.h index 67f1bbc2..d4c04116 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_therm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_therm_gk20a.h @@ -54,18 +54,66 @@ static inline u32 therm_use_a_r(void) { return 0x00020798; } +static inline u32 therm_use_a_ext_therm_0_enable_f(void) +{ + return 0x1; +} +static inline u32 therm_use_a_ext_therm_1_enable_f(void) +{ + return 0x2; +} +static inline u32 therm_use_a_ext_therm_2_enable_f(void) +{ + return 0x4; +} static inline u32 therm_evt_ext_therm_0_r(void) { return 0x00020700; } +static inline u32 therm_evt_ext_therm_0_slow_factor_f(u32 v) +{ + return (v & 0x3f) << 8; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_init_v(void) +{ + return 0x00000000; +} +static inline u32 therm_evt_ext_therm_0_priority_f(u32 v) +{ + return (v & 0x1f) << 24; +} static inline u32 therm_evt_ext_therm_1_r(void) { return 0x00020704; } +static inline u32 therm_evt_ext_therm_1_slow_factor_f(u32 v) +{ + return (v & 0x3f) << 8; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_init_v(void) +{ + return 0x00000000; +} +static inline u32 therm_evt_ext_therm_1_priority_f(u32 v) +{ + return (v & 0x1f) << 24; +} static inline u32 therm_evt_ext_therm_2_r(void) { return 0x00020708; } +static inline u32 therm_evt_ext_therm_2_slow_factor_f(u32 v) +{ + return (v & 0x3f) << 8; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_init_v(void) +{ + return 0x00000000; +} +static inline u32 therm_evt_ext_therm_2_priority_f(u32 v) +{ + return (v & 0x1f) << 24; +} static inline u32 therm_weight_1_r(void) { return 0x00020024; diff --git a/drivers/gpu/nvgpu/gk20a/therm_gk20a.c b/drivers/gpu/nvgpu/gk20a/therm_gk20a.c index fd4149ae..1c1b8419 100644 --- a/drivers/gpu/nvgpu/gk20a/therm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/therm_gk20a.c @@ -3,7 +3,7 @@ * * GK20A Therm * - * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2015, 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, @@ -38,13 +38,20 @@ static int gk20a_init_therm_setup_hw(struct gk20a *g) u32 v; /* program NV_THERM registers */ - gk20a_writel(g, therm_use_a_r(), NV_THERM_USE_A_INIT); + gk20a_writel(g, therm_use_a_r(), therm_use_a_ext_therm_0_enable_f() | + therm_use_a_ext_therm_1_enable_f() | + therm_use_a_ext_therm_2_enable_f()); + /* priority for EXT_THERM_0 event set to highest */ gk20a_writel(g, therm_evt_ext_therm_0_r(), - NV_THERM_EVT_EXT_THERM_0_INIT); + therm_evt_ext_therm_0_slow_factor_f(1) | + therm_evt_ext_therm_0_priority_f(3)); gk20a_writel(g, therm_evt_ext_therm_1_r(), - NV_THERM_EVT_EXT_THERM_1_INIT); + therm_evt_ext_therm_1_slow_factor_f(2) | + therm_evt_ext_therm_1_priority_f(2)); gk20a_writel(g, therm_evt_ext_therm_2_r(), - NV_THERM_EVT_EXT_THERM_2_INIT); + therm_evt_ext_therm_2_slow_factor_f(3) | + therm_evt_ext_therm_2_priority_f(1)); + gk20a_writel(g, therm_grad_stepping_table_r(0), therm_grad_stepping_table_slowdown_factor0_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f()) | @@ -92,9 +99,15 @@ int gk20a_init_therm_support(struct gk20a *g) if (err) return err; - err = gk20a_init_therm_setup_hw(g); + if (g->ops.therm.init_therm_setup_hw) + err = g->ops.therm.init_therm_setup_hw(g); if (err) return err; return err; } + +void gk20a_init_therm_ops(struct gpu_ops *gops) +{ + gops->therm.init_therm_setup_hw = gk20a_init_therm_setup_hw; +} diff --git a/drivers/gpu/nvgpu/gk20a/therm_gk20a.h b/drivers/gpu/nvgpu/gk20a/therm_gk20a.h index e670ec0e..80671d68 100644 --- a/drivers/gpu/nvgpu/gk20a/therm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/therm_gk20a.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 - 2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011 - 2015, 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, @@ -16,13 +16,8 @@ #ifndef THERM_GK20A_H #define THERM_GK20A_H -/* priority for EXT_THERM_0 event set to highest */ -#define NV_THERM_EVT_EXT_THERM_0_INIT 0x3000100 -#define NV_THERM_EVT_EXT_THERM_1_INIT 0x2000200 -#define NV_THERM_EVT_EXT_THERM_2_INIT 0x1000300 -/* configures the thermal events that may cause clock slowdown */ -#define NV_THERM_USE_A_INIT 0x7 +struct gpu_ops; +void gk20a_init_therm_ops(struct gpu_ops *gops); int gk20a_init_therm_support(struct gk20a *g); - #endif /* THERM_GK20A_H */ diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index e57ef7ec..5fe01833 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c @@ -33,6 +33,7 @@ #include "regops_gm20b.h" #include "debug_gm20b.h" #include "cde_gm20b.h" +#include "therm_gm20b.h" #define FUSE_OPT_PRIV_SEC_DIS_0 0x264 #define PRIV_SECURITY_DISABLE 0x01 @@ -136,6 +137,7 @@ int gm20b_init_hal(struct gk20a *g) gm20b_init_regops(gops); gm20b_init_debug_ops(gops); gm20b_init_cde_ops(gops); + gm20b_init_therm_ops(gops); gops->name = "gm20b"; c->twod_class = FERMI_TWOD_A; diff --git a/drivers/gpu/nvgpu/gm20b/hw_therm_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_therm_gm20b.h index 9943cf31..5a696409 100644 --- a/drivers/gpu/nvgpu/gm20b/hw_therm_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/hw_therm_gm20b.h @@ -54,18 +54,54 @@ static inline u32 therm_use_a_r(void) { return 0x00020798; } +static inline u32 therm_use_a_ext_therm_0_enable_f(void) +{ + return 0x1; +} +static inline u32 therm_use_a_ext_therm_1_enable_f(void) +{ + return 0x2; +} +static inline u32 therm_use_a_ext_therm_2_enable_f(void) +{ + return 0x4; +} static inline u32 therm_evt_ext_therm_0_r(void) { return 0x00020700; } +static inline u32 therm_evt_ext_therm_0_slow_factor_f(u32 v) +{ + return (v & 0x3f) << 8; +} +static inline u32 therm_evt_ext_therm_0_slow_factor_init_v(void) +{ + return 0x00000000; +} static inline u32 therm_evt_ext_therm_1_r(void) { return 0x00020704; } +static inline u32 therm_evt_ext_therm_1_slow_factor_f(u32 v) +{ + return (v & 0x3f) << 8; +} +static inline u32 therm_evt_ext_therm_1_slow_factor_init_v(void) +{ + return 0x00000000; +} static inline u32 therm_evt_ext_therm_2_r(void) { return 0x00020708; } +static inline u32 therm_evt_ext_therm_2_slow_factor_f(u32 v) +{ + return (v & 0x3f) << 8; +} +static inline u32 therm_evt_ext_therm_2_slow_factor_init_v(void) +{ + return 0x00000000; +} static inline u32 therm_weight_1_r(void) { return 0x00020024; diff --git a/drivers/gpu/nvgpu/gm20b/therm_gm20b.c b/drivers/gpu/nvgpu/gm20b/therm_gm20b.c new file mode 100644 index 00000000..ed1e0f49 --- /dev/null +++ b/drivers/gpu/nvgpu/gm20b/therm_gm20b.c @@ -0,0 +1,72 @@ +/* + * GM20B THERMAL + * + * Copyright (c) 2015, 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. + */ + +#include "gk20a/gk20a.h" +#include "hw_therm_gm20b.h" + +static int gm20b_init_therm_setup_hw(struct gk20a *g) +{ + u32 v; + + gk20a_dbg_fn(""); + + /* program NV_THERM registers */ + gk20a_writel(g, therm_use_a_r(), therm_use_a_ext_therm_0_enable_f() | + therm_use_a_ext_therm_1_enable_f() | + therm_use_a_ext_therm_2_enable_f()); + gk20a_writel(g, therm_evt_ext_therm_0_r(), + therm_evt_ext_therm_0_slow_factor_f(1)); + gk20a_writel(g, therm_evt_ext_therm_1_r(), + therm_evt_ext_therm_1_slow_factor_f(2)); + gk20a_writel(g, therm_evt_ext_therm_2_r(), + therm_evt_ext_therm_2_slow_factor_f(3)); + + gk20a_writel(g, therm_grad_stepping_table_r(0), + therm_grad_stepping_table_slowdown_factor0_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f()) | + therm_grad_stepping_table_slowdown_factor1_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f()) | + therm_grad_stepping_table_slowdown_factor2_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f()) | + therm_grad_stepping_table_slowdown_factor3_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) | + therm_grad_stepping_table_slowdown_factor4_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f())); + gk20a_writel(g, therm_grad_stepping_table_r(1), + therm_grad_stepping_table_slowdown_factor0_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) | + therm_grad_stepping_table_slowdown_factor1_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) | + therm_grad_stepping_table_slowdown_factor2_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) | + therm_grad_stepping_table_slowdown_factor3_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) | + therm_grad_stepping_table_slowdown_factor4_f(therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f())); + + v = gk20a_readl(g, therm_clk_timing_r(0)); + v |= therm_clk_timing_grad_slowdown_enabled_f(); + gk20a_writel(g, therm_clk_timing_r(0), v); + + v = gk20a_readl(g, therm_config2_r()); + v |= therm_config2_grad_enable_f(1); + v |= therm_config2_slowdown_factor_extended_f(1); + gk20a_writel(g, therm_config2_r(), v); + + gk20a_writel(g, therm_grad_stepping1_r(), + therm_grad_stepping1_pdiv_duration_f(32)); + + v = gk20a_readl(g, therm_grad_stepping0_r()); + v |= therm_grad_stepping0_feature_enable_f(); + gk20a_writel(g, therm_grad_stepping0_r(), v); + + return 0; +} + +void gm20b_init_therm_ops(struct gpu_ops *gops) +{ + gops->therm.init_therm_setup_hw = gm20b_init_therm_setup_hw; + +} diff --git a/drivers/gpu/nvgpu/gm20b/therm_gm20b.h b/drivers/gpu/nvgpu/gm20b/therm_gm20b.h new file mode 100644 index 00000000..c346c4f2 --- /dev/null +++ b/drivers/gpu/nvgpu/gm20b/therm_gm20b.h @@ -0,0 +1,21 @@ +/* + * GM20B THERMAL + * + * Copyright (c) 2015, 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. + */ +#ifndef THERM_GM20B_H +#define THERM_GM20B_H + +struct gpu_ops; +void gm20b_init_therm_ops(struct gpu_ops *gops); + +#endif /* THERM_GM20B_H */ -- cgit v1.2.2