summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b/therm_gp10b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b/therm_gp10b.c')
-rw-r--r--drivers/gpu/nvgpu/gp10b/therm_gp10b.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/therm_gp10b.c b/drivers/gpu/nvgpu/gp10b/therm_gp10b.c
new file mode 100644
index 00000000..7f43cb56
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/therm_gp10b.c
@@ -0,0 +1,130 @@
1/*
2 * drivers/gpu/nvgpu/gm20b/therm_gk20a.c
3 *
4 * GP10B Therm
5 *
6 * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 */
17
18#include "gk20a/gk20a.h"
19#include "hw_therm_gp10b.h"
20
21static int gp10b_init_therm_setup_hw(struct gk20a *g)
22{
23 u32 v;
24
25 gk20a_dbg_fn("");
26
27 /* program NV_THERM registers */
28 gk20a_writel(g, therm_use_a_r(), therm_use_a_ext_therm_0_enable_f() |
29 therm_use_a_ext_therm_1_enable_f() |
30 therm_use_a_ext_therm_2_enable_f());
31 gk20a_writel(g, therm_evt_ext_therm_0_r(),
32 therm_evt_ext_therm_0_slow_factor_f(0x2));
33 gk20a_writel(g, therm_evt_ext_therm_1_r(),
34 therm_evt_ext_therm_1_slow_factor_f(0x6));
35 gk20a_writel(g, therm_evt_ext_therm_2_r(),
36 therm_evt_ext_therm_2_slow_factor_f(0xe));
37
38 gk20a_writel(g, therm_grad_stepping_table_r(0),
39 therm_grad_stepping_table_slowdown_factor0_f(
40 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f()) |
41 therm_grad_stepping_table_slowdown_factor1_f(
42 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f()) |
43 therm_grad_stepping_table_slowdown_factor2_f(
44 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f()) |
45 therm_grad_stepping_table_slowdown_factor3_f(
46 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
47 therm_grad_stepping_table_slowdown_factor4_f(
48 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()));
49
50 gk20a_writel(g, therm_grad_stepping_table_r(1),
51 therm_grad_stepping_table_slowdown_factor0_f(
52 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
53 therm_grad_stepping_table_slowdown_factor1_f(
54 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
55 therm_grad_stepping_table_slowdown_factor2_f(
56 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
57 therm_grad_stepping_table_slowdown_factor3_f(
58 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
59 therm_grad_stepping_table_slowdown_factor4_f(
60 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()));
61
62 v = gk20a_readl(g, therm_clk_timing_r(0));
63 v |= therm_clk_timing_grad_slowdown_enabled_f();
64 gk20a_writel(g, therm_clk_timing_r(0), v);
65
66 v = gk20a_readl(g, therm_config2_r());
67 v |= therm_config2_grad_enable_f(1);
68 v |= therm_config2_slowdown_factor_extended_f(1);
69 gk20a_writel(g, therm_config2_r(), v);
70
71 gk20a_writel(g, therm_grad_stepping1_r(),
72 therm_grad_stepping1_pdiv_duration_f(32));
73
74 v = gk20a_readl(g, therm_grad_stepping0_r());
75 v |= therm_grad_stepping0_feature_enable_f();
76 gk20a_writel(g, therm_grad_stepping0_r(), v);
77
78 return 0;
79}
80
81static int gp10b_elcg_init_idle_filters(struct gk20a *g)
82{
83 u32 gate_ctrl, idle_filter;
84 u32 engine_id;
85 u32 active_engine_id = 0;
86 struct fifo_gk20a *f = &g->fifo;
87
88 gk20a_dbg_fn("");
89
90 for (engine_id = 0; engine_id < f->num_engines; engine_id++) {
91 active_engine_id = f->active_engines_list[engine_id];
92 gate_ctrl = gk20a_readl(g, therm_gate_ctrl_r(active_engine_id));
93
94 if (tegra_platform_is_linsim()) {
95 gate_ctrl = set_field(gate_ctrl,
96 therm_gate_ctrl_eng_delay_after_m(),
97 therm_gate_ctrl_eng_delay_after_f(4));
98 }
99
100 /* 2 * (1 << 9) = 1024 clks */
101 gate_ctrl = set_field(gate_ctrl,
102 therm_gate_ctrl_eng_idle_filt_exp_m(),
103 therm_gate_ctrl_eng_idle_filt_exp_f(9));
104 gate_ctrl = set_field(gate_ctrl,
105 therm_gate_ctrl_eng_idle_filt_mant_m(),
106 therm_gate_ctrl_eng_idle_filt_mant_f(2));
107 gate_ctrl = set_field(gate_ctrl,
108 therm_gate_ctrl_eng_delay_before_m(),
109 therm_gate_ctrl_eng_delay_before_f(4));
110 gk20a_writel(g, therm_gate_ctrl_r(active_engine_id), gate_ctrl);
111 }
112
113 /* default fecs_idle_filter to 0 */
114 idle_filter = gk20a_readl(g, therm_fecs_idle_filter_r());
115 idle_filter &= ~therm_fecs_idle_filter_value_m();
116 gk20a_writel(g, therm_fecs_idle_filter_r(), idle_filter);
117 /* default hubmmu_idle_filter to 0 */
118 idle_filter = gk20a_readl(g, therm_hubmmu_idle_filter_r());
119 idle_filter &= ~therm_hubmmu_idle_filter_value_m();
120 gk20a_writel(g, therm_hubmmu_idle_filter_r(), idle_filter);
121
122 gk20a_dbg_fn("done");
123 return 0;
124}
125
126void gp10b_init_therm_ops(struct gpu_ops *gops)
127{
128 gops->therm.init_therm_setup_hw = gp10b_init_therm_setup_hw;
129 gops->therm.elcg_init_idle_filters = gp10b_elcg_init_idle_filters;
130}