From 18558fc9be7a3a6f0c8d9ac8509ba1b52bb88d33 Mon Sep 17 00:00:00 2001 From: Seshendra Gadagottu Date: Tue, 19 Feb 2019 15:07:41 -0800 Subject: [PATCH] gpu: nvgpu: move thermal related code to thermal unit gm20b clocks is accessing thermal registers directly in several places. Moved all this code to thermal unit and clock code is accessing these through provided thermal hal functions. Following new hal are defined in thermal unit for enabling/disabling throttling and enabling/disabling idle slowdown: void (*throttle_enable)(struct gk20a *g, u32 val); int (*throttle_disable)(struct gk20a *g); void (*idle_slowdown_enable)(struct gk20a *g, u32 val); int (*idle_slowdown_disable)(struct gk20a *g); At this moment, these hals are getting used only by gm20b code. JIRA NVGPU-2001 Change-Id: I937a7c76dfae9aa7e86f23c53f84fae9a9dda13e Signed-off-by: Seshendra Gadagottu Reviewed-on: https://git-master.nvidia.com/r/2023289 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/therm/therm_gm20b.c | 29 ++++++++++- drivers/gpu/nvgpu/common/therm/therm_gm20b.h | 6 ++- drivers/gpu/nvgpu/gm20b/clk_gm20b.c | 51 ++++++-------------- drivers/gpu/nvgpu/gm20b/hal_gm20b.c | 4 ++ drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 4 ++ 5 files changed, 56 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/nvgpu/common/therm/therm_gm20b.c b/drivers/gpu/nvgpu/common/therm/therm_gm20b.c index 524d702ec..6ff8df883 100644 --- a/drivers/gpu/nvgpu/common/therm/therm_gm20b.c +++ b/drivers/gpu/nvgpu/common/therm/therm_gm20b.c @@ -1,7 +1,7 @@ /* * GM20B THERMAL * - * Copyright (c) 2015-2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -194,3 +194,30 @@ void gm20b_therm_init_elcg_mode(struct gk20a *g, u32 mode, u32 engine) gk20a_writel(g, therm_gate_ctrl_r(engine), gate_ctrl); } + +void gm20b_therm_throttle_enable(struct gk20a *g, u32 val) +{ + gk20a_writel(g, therm_use_a_r(), val); +} + +u32 gm20b_therm_throttle_disable(struct gk20a *g) +{ + u32 val = gk20a_readl(g, therm_use_a_r()); + gk20a_writel(g, therm_use_a_r(), 0); + return val; +} + +void gm20b_therm_idle_slowdown_enable(struct gk20a *g, u32 val) +{ + gk20a_writel(g, therm_clk_slowdown_r(0), val); +} + +u32 gm20b_therm_idle_slowdown_disable(struct gk20a *g) +{ + u32 saved_val = gk20a_readl(g, therm_clk_slowdown_r(0)); + u32 val = set_field(saved_val, therm_clk_slowdown_idle_factor_m(), + therm_clk_slowdown_idle_factor_disabled_f()); + nvgpu_writel_check(g, therm_clk_slowdown_r(0), val); + + return saved_val; +} diff --git a/drivers/gpu/nvgpu/common/therm/therm_gm20b.h b/drivers/gpu/nvgpu/common/therm/therm_gm20b.h index b6dfc5b61..eac2d122a 100644 --- a/drivers/gpu/nvgpu/common/therm/therm_gm20b.h +++ b/drivers/gpu/nvgpu/common/therm/therm_gm20b.h @@ -1,7 +1,7 @@ /* * GM20B THERMAL * - * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,5 +29,9 @@ int gm20b_init_therm_setup_hw(struct gk20a *g); int gm20b_elcg_init_idle_filters(struct gk20a *g); void gm20b_therm_init_elcg_mode(struct gk20a *g, u32 mode, u32 engine); void gm20b_therm_init_blcg_mode(struct gk20a *g, u32 mode, u32 engine); +void gm20b_therm_throttle_enable(struct gk20a *g, u32 val); +u32 gm20b_therm_throttle_disable(struct gk20a *g); +void gm20b_therm_idle_slowdown_enable(struct gk20a *g, u32 val); +u32 gm20b_therm_idle_slowdown_disable(struct gk20a *g); #endif /* THERM_GM20B_H */ diff --git a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c index fbf6de696..e4ff62b45 100644 --- a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c @@ -31,11 +31,11 @@ #include #include #include +#include #include "clk_gm20b.h" #include -#include #include #define gk20a_dbg_clk(g, fmt, arg...) \ @@ -718,30 +718,18 @@ static int clk_slide_gpc_pll(struct gk20a *g, struct pll *gpll) return 0; } -static void throttle_enable(struct gk20a *g, u32 val) -{ - gk20a_writel(g, therm_use_a_r(), val); -} - -static u32 throttle_disable(struct gk20a *g) -{ - u32 val = gk20a_readl(g, therm_use_a_r()); - gk20a_writel(g, therm_use_a_r(), 0); - return val; -} - /* GPCPLL bypass methods */ static void clk_change_pldiv_under_bypass(struct gk20a *g, struct pll *gpll) { u32 data, coeff, throt; /* put PLL in bypass before programming it */ - throt = throttle_disable(g); + throt = g->ops.therm.throttle_disable(g); data = gk20a_readl(g, trim_sys_sel_vco_r()); data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), trim_sys_sel_vco_gpc2clk_out_bypass_f()); gk20a_writel(g, trim_sys_sel_vco_r(), data); - throttle_enable(g, throt); + g->ops.therm.throttle_enable(g, throt); /* change PLDIV */ coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r()); @@ -751,13 +739,13 @@ static void clk_change_pldiv_under_bypass(struct gk20a *g, struct pll *gpll) gk20a_writel(g, trim_sys_gpcpll_coeff_r(), coeff); /* put PLL back on vco */ - throt = throttle_disable(g); + throt = g->ops.therm.throttle_disable(g); data = gk20a_readl(g, trim_sys_sel_vco_r()); nvgpu_udelay(1); data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), trim_sys_sel_vco_gpc2clk_out_vco_f()); gk20a_writel(g, trim_sys_sel_vco_r(), data); - throttle_enable(g, throt); + g->ops.therm.throttle_enable(g, throt); } static void clk_lock_gpc_pll_under_bypass(struct gk20a *g, struct pll *gpll) @@ -765,12 +753,12 @@ static void clk_lock_gpc_pll_under_bypass(struct gk20a *g, struct pll *gpll) u32 data, cfg, coeff, timeout, throt; /* put PLL in bypass before programming it */ - throt = throttle_disable(g); + throt = g->ops.therm.throttle_disable(g); data = gk20a_readl(g, trim_sys_sel_vco_r()); data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), trim_sys_sel_vco_gpc2clk_out_bypass_f()); gk20a_writel(g, trim_sys_sel_vco_r(), data); - throttle_enable(g, throt); + g->ops.therm.throttle_enable(g, throt); cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r()); nvgpu_udelay(1); @@ -869,12 +857,12 @@ pll_locked: (void) gk20a_readl(g, trim_sys_gpcpll_cfg_r()); /* put PLL back on vco */ - throt = throttle_disable(g); + throt = g->ops.therm.throttle_disable(g); data = gk20a_readl(g, trim_sys_sel_vco_r()); data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), trim_sys_sel_vco_gpc2clk_out_vco_f()); gk20a_writel(g, trim_sys_sel_vco_r(), data); - throttle_enable(g, throt); + g->ops.therm.throttle_enable(g, throt); } /* @@ -1159,12 +1147,12 @@ static void clk_disable_gpcpll(struct gk20a *g, bool allow_slide) } /* put PLL in bypass before disabling it */ - throt = throttle_disable(g); + throt = g->ops.therm.throttle_disable(g); cfg = gk20a_readl(g, trim_sys_sel_vco_r()); cfg = set_field(cfg, trim_sys_sel_vco_gpc2clk_out_m(), trim_sys_sel_vco_gpc2clk_out_bypass_f()); gk20a_writel(g, trim_sys_sel_vco_r(), cfg); - throttle_enable(g, throt); + g->ops.therm.throttle_enable(g, throt); /* clear SYNC_MODE before disabling PLL */ cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r()); @@ -1393,11 +1381,7 @@ static int gm20b_init_clk_setup_hw(struct gk20a *g) } /* Disable idle slow down */ - data = gk20a_readl(g, therm_clk_slowdown_r(0)); - data = set_field(data, therm_clk_slowdown_idle_factor_m(), - therm_clk_slowdown_idle_factor_disabled_f()); - gk20a_writel(g, therm_clk_slowdown_r(0), data); - (void) gk20a_readl(g, therm_clk_slowdown_r(0)); + data = g->ops.therm.idle_slowdown_disable(g); if (g->clk.gpc_pll.mode == GPC_PLL_MODE_DVFS) { return clk_enbale_pll_dvfs(g); @@ -1540,7 +1524,7 @@ int gm20b_clk_get_voltage(struct clk_gk20a *clk, u64 *val) int gm20b_clk_get_gpcclk_clock_counter(struct clk_gk20a *clk, u64 *val) { struct gk20a *g = clk->g; - u32 clk_slowdown, clk_slowdown_save; + u32 clk_slowdown_save; int err; u32 ncycle = 800; /* count GPCCLK for ncycle of clkin */ @@ -1555,12 +1539,7 @@ int gm20b_clk_get_gpcclk_clock_counter(struct clk_gk20a *clk, u64 *val) nvgpu_mutex_acquire(&g->clk.clk_mutex); /* Disable clock slowdown during measurements */ - clk_slowdown_save = gk20a_readl(g, therm_clk_slowdown_r(0)); - clk_slowdown = set_field(clk_slowdown_save, - therm_clk_slowdown_idle_factor_m(), - therm_clk_slowdown_idle_factor_disabled_f()); - gk20a_writel(g, therm_clk_slowdown_r(0), clk_slowdown); - (void) gk20a_readl(g, therm_clk_slowdown_r(0)); + clk_slowdown_save = g->ops.therm.idle_slowdown_disable(g); gk20a_writel(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0), trim_gpc_clk_cntr_ncgpcclk_cfg_reset_asserted_f()); @@ -1584,7 +1563,7 @@ int gm20b_clk_get_gpcclk_clock_counter(struct clk_gk20a *clk, u64 *val) *val = freq; /* Restore clock slowdown */ - gk20a_writel(g, therm_clk_slowdown_r(0), clk_slowdown_save); + g->ops.therm.idle_slowdown_enable(g, clk_slowdown_save); nvgpu_mutex_release(&g->clk.clk_mutex); gk20a_idle(g); diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index 1139d848a..f067e225f 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c @@ -626,6 +626,10 @@ static const struct gpu_ops gm20b_ops = { .init_elcg_mode = gm20b_therm_init_elcg_mode, .init_blcg_mode = gm20b_therm_init_blcg_mode, .elcg_init_idle_filters = gm20b_elcg_init_idle_filters, + .throttle_enable = gm20b_therm_throttle_enable, + .throttle_disable = gm20b_therm_throttle_disable, + .idle_slowdown_enable = gm20b_therm_idle_slowdown_enable, + .idle_slowdown_disable = gm20b_therm_idle_slowdown_disable, }, .pmu = { .falcon_base_addr = gk20a_pmu_falcon_base_addr, diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index f563c4ed4..f6d79113c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -1169,6 +1169,10 @@ struct gpu_ops { void (*get_internal_sensor_limits)(s32 *max_24_8, s32 *min_24_8); int (*configure_therm_alert)(struct gk20a *g, s32 curr_warn_temp); + void (*throttle_enable)(struct gk20a *g, u32 val); + u32 (*throttle_disable)(struct gk20a *g); + void (*idle_slowdown_enable)(struct gk20a *g, u32 val); + u32 (*idle_slowdown_disable)(struct gk20a *g); } therm; struct { bool (*is_pmu_supported)(struct gk20a *g);