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 <sgadagottu@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2023289
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Seshendra Gadagottu
2019-02-19 15:07:41 -08:00
committed by mobile promotions
parent 7dc84e1b97
commit 18558fc9be
5 changed files with 56 additions and 38 deletions

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -31,11 +31,11 @@
#include <nvgpu/utils.h>
#include <nvgpu/timers.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/therm.h>
#include "clk_gm20b.h"
#include <nvgpu/hw/gm20b/hw_trim_gm20b.h>
#include <nvgpu/hw/gm20b/hw_therm_gm20b.h>
#include <nvgpu/hw/gm20b/hw_fuse_gm20b.h>
#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);

View File

@@ -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,

View File

@@ -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);