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