aboutsummaryrefslogtreecommitdiffstats
path: root/include/clk/clk_freq_controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/clk/clk_freq_controller.c')
-rw-r--r--include/clk/clk_freq_controller.c462
1 files changed, 462 insertions, 0 deletions
diff --git a/include/clk/clk_freq_controller.c b/include/clk/clk_freq_controller.c
new file mode 100644
index 0000000..f4d09b0
--- /dev/null
+++ b/include/clk/clk_freq_controller.c
@@ -0,0 +1,462 @@
1/*
2 * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <nvgpu/bios.h>
24#include <nvgpu/gk20a.h>
25
26#include "clk.h"
27#include "clk_fll.h"
28#include "clk_domain.h"
29#include "clk_freq_controller.h"
30#include "boardobj/boardobjgrp.h"
31#include "boardobj/boardobjgrp_e32.h"
32#include "ctrl/ctrlclk.h"
33#include "ctrl/ctrlvolt.h"
34
35static int clk_freq_controller_pmudatainit_super(struct gk20a *g,
36 struct boardobj *board_obj_ptr,
37 struct nv_pmu_boardobj *ppmudata)
38{
39 struct nv_pmu_clk_clk_freq_controller_boardobj_set *pfreq_cntlr_set;
40 struct clk_freq_controller *pfreq_cntlr;
41 int status = 0;
42
43 status = boardobj_pmudatainit_super(g, board_obj_ptr, ppmudata);
44 if (status) {
45 return status;
46 }
47
48 pfreq_cntlr_set =
49 (struct nv_pmu_clk_clk_freq_controller_boardobj_set *)ppmudata;
50 pfreq_cntlr = (struct clk_freq_controller *)board_obj_ptr;
51
52 pfreq_cntlr_set->controller_id = pfreq_cntlr->controller_id;
53 pfreq_cntlr_set->clk_domain = pfreq_cntlr->clk_domain;
54 pfreq_cntlr_set->parts_freq_mode = pfreq_cntlr->parts_freq_mode;
55 pfreq_cntlr_set->bdisable = pfreq_cntlr->bdisable;
56 pfreq_cntlr_set->freq_cap_noise_unaware_vmin_above =
57 pfreq_cntlr->freq_cap_noise_unaware_vmin_above;
58 pfreq_cntlr_set->freq_cap_noise_unaware_vmin_below =
59 pfreq_cntlr->freq_cap_noise_unaware_vmin_below;
60 pfreq_cntlr_set->freq_hyst_pos_mhz = pfreq_cntlr->freq_hyst_pos_mhz;
61 pfreq_cntlr_set->freq_hyst_neg_mhz = pfreq_cntlr->freq_hyst_neg_mhz;
62
63 return status;
64}
65
66static int clk_freq_controller_pmudatainit_pi(struct gk20a *g,
67 struct boardobj *board_obj_ptr,
68 struct nv_pmu_boardobj *ppmudata)
69{
70 struct nv_pmu_clk_clk_freq_controller_pi_boardobj_set
71 *pfreq_cntlr_pi_set;
72 struct clk_freq_controller_pi *pfreq_cntlr_pi;
73 int status = 0;
74
75 status = clk_freq_controller_pmudatainit_super(g,
76 board_obj_ptr, ppmudata);
77 if (status) {
78 return -1;
79 }
80
81 pfreq_cntlr_pi_set =
82 (struct nv_pmu_clk_clk_freq_controller_pi_boardobj_set *)
83 ppmudata;
84 pfreq_cntlr_pi = (struct clk_freq_controller_pi *)board_obj_ptr;
85
86 pfreq_cntlr_pi_set->prop_gain = pfreq_cntlr_pi->prop_gain;
87 pfreq_cntlr_pi_set->integ_gain = pfreq_cntlr_pi->integ_gain;
88 pfreq_cntlr_pi_set->integ_decay = pfreq_cntlr_pi->integ_decay;
89 pfreq_cntlr_pi_set->volt_delta_min = pfreq_cntlr_pi->volt_delta_min;
90 pfreq_cntlr_pi_set->volt_delta_max = pfreq_cntlr_pi->volt_delta_max;
91 pfreq_cntlr_pi_set->slowdown_pct_min = pfreq_cntlr_pi->slowdown_pct_min;
92 pfreq_cntlr_pi_set->bpoison = pfreq_cntlr_pi->bpoison;
93
94 return status;
95}
96
97static int clk_freq_controller_construct_super(struct gk20a *g,
98 struct boardobj **ppboardobj,
99 u16 size, void *pargs)
100{
101 struct clk_freq_controller *pfreq_cntlr = NULL;
102 struct clk_freq_controller *pfreq_cntlr_tmp = NULL;
103 int status = 0;
104
105 status = boardobj_construct_super(g, ppboardobj, size, pargs);
106 if (status) {
107 return -EINVAL;
108 }
109
110 pfreq_cntlr_tmp = (struct clk_freq_controller *)pargs;
111 pfreq_cntlr = (struct clk_freq_controller *)*ppboardobj;
112
113 pfreq_cntlr->super.pmudatainit = clk_freq_controller_pmudatainit_super;
114
115 pfreq_cntlr->controller_id = pfreq_cntlr_tmp->controller_id;
116 pfreq_cntlr->clk_domain = pfreq_cntlr_tmp->clk_domain;
117 pfreq_cntlr->parts_freq_mode = pfreq_cntlr_tmp->parts_freq_mode;
118 pfreq_cntlr->freq_cap_noise_unaware_vmin_above =
119 pfreq_cntlr_tmp->freq_cap_noise_unaware_vmin_above;
120 pfreq_cntlr->freq_cap_noise_unaware_vmin_below =
121 pfreq_cntlr_tmp->freq_cap_noise_unaware_vmin_below;
122 pfreq_cntlr->freq_hyst_pos_mhz = pfreq_cntlr_tmp->freq_hyst_pos_mhz;
123 pfreq_cntlr->freq_hyst_neg_mhz = pfreq_cntlr_tmp->freq_hyst_neg_mhz;
124
125 return status;
126}
127
128static int clk_freq_controller_construct_pi(struct gk20a *g,
129 struct boardobj **ppboardobj,
130 u16 size, void *pargs)
131{
132 struct clk_freq_controller_pi *pfreq_cntlr_pi = NULL;
133 struct clk_freq_controller_pi *pfreq_cntlr_pi_tmp = NULL;
134 int status = 0;
135
136 status = clk_freq_controller_construct_super(g, ppboardobj,
137 size, pargs);
138 if (status) {
139 return -EINVAL;
140 }
141
142 pfreq_cntlr_pi = (struct clk_freq_controller_pi *)*ppboardobj;
143 pfreq_cntlr_pi_tmp = (struct clk_freq_controller_pi *)pargs;
144
145 pfreq_cntlr_pi->super.super.pmudatainit =
146 clk_freq_controller_pmudatainit_pi;
147
148 pfreq_cntlr_pi->prop_gain = pfreq_cntlr_pi_tmp->prop_gain;
149 pfreq_cntlr_pi->integ_gain = pfreq_cntlr_pi_tmp->integ_gain;
150 pfreq_cntlr_pi->integ_decay = pfreq_cntlr_pi_tmp->integ_decay;
151 pfreq_cntlr_pi->volt_delta_min = pfreq_cntlr_pi_tmp->volt_delta_min;
152 pfreq_cntlr_pi->volt_delta_max = pfreq_cntlr_pi_tmp->volt_delta_max;
153 pfreq_cntlr_pi->slowdown_pct_min = pfreq_cntlr_pi_tmp->slowdown_pct_min;
154 pfreq_cntlr_pi->bpoison = pfreq_cntlr_pi_tmp->bpoison;
155
156 return status;
157}
158
159static struct clk_freq_controller *clk_clk_freq_controller_construct(
160 struct gk20a *g,
161 void *pargs)
162{
163 struct boardobj *board_obj_ptr = NULL;
164 int status = 0;
165
166 if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_FREQ_CONTROLLER_TYPE_PI) {
167 return NULL;
168 }
169
170 status = clk_freq_controller_construct_pi(g, &board_obj_ptr,
171 sizeof(struct clk_freq_controller_pi), pargs);
172 if (status) {
173 return NULL;
174 }
175
176 return (struct clk_freq_controller *)board_obj_ptr;
177}
178
179
180static int clk_get_freq_controller_table(struct gk20a *g,
181 struct clk_freq_controllers *pclk_freq_controllers)
182{
183 int status = 0;
184 u8 *pfreq_controller_table_ptr = NULL;
185 struct vbios_fct_1x_header header = { 0 };
186 struct vbios_fct_1x_entry entry = { 0 };
187 u8 entry_idx;
188 u8 *entry_offset;
189 struct clk_freq_controller *pclk_freq_cntr = NULL;
190 struct clk_freq_controller *ptmp_freq_cntr = NULL;
191 struct clk_freq_controller_pi *ptmp_freq_cntr_pi = NULL;
192 struct clk_domain *pclk_domain;
193
194 struct freq_controller_data_type {
195 union {
196 struct boardobj board_obj;
197 struct clk_freq_controller freq_controller;
198 struct clk_freq_controller_pi freq_controller_pi;
199 };
200 } freq_controller_data;
201
202 pfreq_controller_table_ptr =
203 (u8 *)nvgpu_bios_get_perf_table_ptrs(g,
204 g->bios.clock_token,
205 FREQUENCY_CONTROLLER_TABLE);
206 if (pfreq_controller_table_ptr == NULL) {
207 status = -EINVAL;
208 goto done;
209 }
210
211 memcpy(&header, pfreq_controller_table_ptr,
212 sizeof(struct vbios_fct_1x_header));
213