This source file includes following definitions.
- convert_and_clamp
- dcn21_dchvm_init
- hubbub21_init_dchub
- hubbub21_program_urgent_watermarks
- hubbub21_program_stutter_watermarks
- hubbub21_program_pstate_watermarks
- hubbub21_program_watermarks
- hubbub21_wm_read_state
- hubbub21_construct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include <linux/delay.h>
26 #include "dm_services.h"
27 #include "dcn20/dcn20_hubbub.h"
28 #include "dcn21_hubbub.h"
29 #include "reg_helper.h"
30
31 #define REG(reg)\
32 hubbub1->regs->reg
33 #define DC_LOGGER \
34 hubbub1->base.ctx->logger
35 #define CTX \
36 hubbub1->base.ctx
37
38 #undef FN
39 #define FN(reg_name, field_name) \
40 hubbub1->shifts->field_name, hubbub1->masks->field_name
41
42 #define REG(reg)\
43 hubbub1->regs->reg
44
45 #define CTX \
46 hubbub1->base.ctx
47
48 #undef FN
49 #define FN(reg_name, field_name) \
50 hubbub1->shifts->field_name, hubbub1->masks->field_name
51
52 #ifdef NUM_VMID
53 #undef NUM_VMID
54 #endif
55 #define NUM_VMID 1
56
57 static uint32_t convert_and_clamp(
58 uint32_t wm_ns,
59 uint32_t refclk_mhz,
60 uint32_t clamp_value)
61 {
62 uint32_t ret_val = 0;
63 ret_val = wm_ns * refclk_mhz;
64 ret_val /= 1000;
65
66 if (ret_val > clamp_value)
67 ret_val = clamp_value;
68
69 return ret_val;
70 }
71
72 void dcn21_dchvm_init(struct hubbub *hubbub)
73 {
74 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
75 uint32_t riommu_active;
76 int i;
77
78
79 REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1);
80
81
82 for (i = 0; i < 100; i++) {
83 REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active);
84
85 if (riommu_active)
86 break;
87 else
88 udelay(5);
89 }
90
91 if (riommu_active) {
92
93 REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1);
94
95
96 REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1);
97
98
99 REG_UPDATE_4(DCHVM_CLK_CTRL,
100 HVM_DISPCLK_R_GATE_DIS, 0,
101 HVM_DISPCLK_G_GATE_DIS, 0,
102 HVM_DCFCLK_R_GATE_DIS, 0,
103 HVM_DCFCLK_G_GATE_DIS, 0);
104
105
106 REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100);
107 }
108 }
109
110 static int hubbub21_init_dchub(struct hubbub *hubbub,
111 struct dcn_hubbub_phys_addr_config *pa_config)
112 {
113 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
114
115 REG_SET(DCN_VM_FB_LOCATION_BASE, 0,
116 FB_BASE, pa_config->system_aperture.fb_base);
117 REG_SET(DCN_VM_FB_LOCATION_TOP, 0,
118 FB_TOP, pa_config->system_aperture.fb_top);
119 REG_SET(DCN_VM_FB_OFFSET, 0,
120 FB_OFFSET, pa_config->system_aperture.fb_offset);
121 REG_SET(DCN_VM_AGP_BOT, 0,
122 AGP_BOT, pa_config->system_aperture.agp_bot);
123 REG_SET(DCN_VM_AGP_TOP, 0,
124 AGP_TOP, pa_config->system_aperture.agp_top);
125 REG_SET(DCN_VM_AGP_BASE, 0,
126 AGP_BASE, pa_config->system_aperture.agp_base);
127
128 dcn21_dchvm_init(hubbub);
129
130 return NUM_VMID;
131 }
132
133 static void hubbub21_program_urgent_watermarks(
134 struct hubbub *hubbub,
135 struct dcn_watermark_set *watermarks,
136 unsigned int refclk_mhz,
137 bool safe_to_lower)
138 {
139 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
140 uint32_t prog_wm_value;
141
142
143
144 if (safe_to_lower || watermarks->a.urgent_ns > hubbub1->watermarks.a.urgent_ns) {
145 hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
146 prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
147 refclk_mhz, 0x1fffff);
148 REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
149 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value,
150 DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value);
151
152 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
153 "HW register value = 0x%x\n",
154 watermarks->a.urgent_ns, prog_wm_value);
155 }
156
157
158 if (safe_to_lower || watermarks->a.frac_urg_bw_flip
159 > hubbub1->watermarks.a.frac_urg_bw_flip) {
160 hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
161
162 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0,
163 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip);
164 }
165
166 if (safe_to_lower || watermarks->a.frac_urg_bw_nom
167 > hubbub1->watermarks.a.frac_urg_bw_nom) {
168 hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
169
170 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
171 DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom);
172 }
173
174
175 if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
176 hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
177 prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
178 refclk_mhz, 0x1fffff);
179 REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
180 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value,
181 DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_B, prog_wm_value);
182
183 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
184 "HW register value = 0x%x\n",
185 watermarks->b.urgent_ns, prog_wm_value);
186 }
187
188
189 if (safe_to_lower || watermarks->a.frac_urg_bw_flip
190 > hubbub1->watermarks.a.frac_urg_bw_flip) {
191 hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
192
193 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0,
194 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->a.frac_urg_bw_flip);
195 }
196
197 if (safe_to_lower || watermarks->a.frac_urg_bw_nom
198 > hubbub1->watermarks.a.frac_urg_bw_nom) {
199 hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
200
201 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0,
202 DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom);
203 }
204
205
206 if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
207 hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
208 prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
209 refclk_mhz, 0x1fffff);
210 REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
211 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value,
212 DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_C, prog_wm_value);
213
214 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
215 "HW register value = 0x%x\n",
216 watermarks->c.urgent_ns, prog_wm_value);
217 }
218
219
220 if (safe_to_lower || watermarks->a.frac_urg_bw_flip
221 > hubbub1->watermarks.a.frac_urg_bw_flip) {
222 hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
223
224 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0,
225 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->a.frac_urg_bw_flip);
226 }
227
228 if (safe_to_lower || watermarks->a.frac_urg_bw_nom
229 > hubbub1->watermarks.a.frac_urg_bw_nom) {
230 hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
231
232 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0,
233 DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom);
234 }
235
236
237 if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
238 hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
239 prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
240 refclk_mhz, 0x1fffff);
241 REG_SET_2(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
242 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value,
243 DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_D, prog_wm_value);
244
245 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
246 "HW register value = 0x%x\n",
247 watermarks->d.urgent_ns, prog_wm_value);
248 }
249
250
251 if (safe_to_lower || watermarks->a.frac_urg_bw_flip
252 > hubbub1->watermarks.a.frac_urg_bw_flip) {
253 hubbub1->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
254
255 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0,
256 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->a.frac_urg_bw_flip);
257 }
258
259 if (safe_to_lower || watermarks->a.frac_urg_bw_nom
260 > hubbub1->watermarks.a.frac_urg_bw_nom) {
261 hubbub1->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
262
263 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0,
264 DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom);
265 }
266 }
267
268 static void hubbub21_program_stutter_watermarks(
269 struct hubbub *hubbub,
270 struct dcn_watermark_set *watermarks,
271 unsigned int refclk_mhz,
272 bool safe_to_lower)
273 {
274 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
275 uint32_t prog_wm_value;
276
277
278 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
279 > hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
280 hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
281 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
282 prog_wm_value = convert_and_clamp(
283 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
284 refclk_mhz, 0x1fffff);
285 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
286 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value,
287 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
288 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
289 "HW register value = 0x%x\n",
290 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
291 }
292
293 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
294 > hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) {
295 hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns =
296 watermarks->a.cstate_pstate.cstate_exit_ns;
297 prog_wm_value = convert_and_clamp(
298 watermarks->a.cstate_pstate.cstate_exit_ns,
299 refclk_mhz, 0x1fffff);
300 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
301 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value,
302 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
303 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
304 "HW register value = 0x%x\n",
305 watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
306 }
307
308
309 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
310 > hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
311 hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
312 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
313 prog_wm_value = convert_and_clamp(
314 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
315 refclk_mhz, 0x1fffff);
316 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
317 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value,
318 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
319 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
320 "HW register value = 0x%x\n",
321 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
322 }
323
324 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
325 > hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) {
326 hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns =
327 watermarks->b.cstate_pstate.cstate_exit_ns;
328 prog_wm_value = convert_and_clamp(
329 watermarks->b.cstate_pstate.cstate_exit_ns,
330 refclk_mhz, 0x1fffff);
331 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
332 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value,
333 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
334 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
335 "HW register value = 0x%x\n",
336 watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
337 }
338
339
340 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
341 > hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
342 hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
343 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
344 prog_wm_value = convert_and_clamp(
345 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
346 refclk_mhz, 0x1fffff);
347 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
348 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value,
349 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
350 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
351 "HW register value = 0x%x\n",
352 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
353 }
354
355 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
356 > hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) {
357 hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns =
358 watermarks->c.cstate_pstate.cstate_exit_ns;
359 prog_wm_value = convert_and_clamp(
360 watermarks->c.cstate_pstate.cstate_exit_ns,
361 refclk_mhz, 0x1fffff);
362 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
363 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value,
364 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
365 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
366 "HW register value = 0x%x\n",
367 watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
368 }
369
370
371 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
372 > hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
373 hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
374 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
375 prog_wm_value = convert_and_clamp(
376 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
377 refclk_mhz, 0x1fffff);
378 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
379 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value,
380 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
381 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
382 "HW register value = 0x%x\n",
383 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
384 }
385
386 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
387 > hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) {
388 hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns =
389 watermarks->d.cstate_pstate.cstate_exit_ns;
390 prog_wm_value = convert_and_clamp(
391 watermarks->d.cstate_pstate.cstate_exit_ns,
392 refclk_mhz, 0x1fffff);
393 REG_SET_2(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
394 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value,
395 DCHUBBUB_ARB_VM_ROW_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
396 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
397 "HW register value = 0x%x\n",
398 watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
399 }
400 }
401
402 static void hubbub21_program_pstate_watermarks(
403 struct hubbub *hubbub,
404 struct dcn_watermark_set *watermarks,
405 unsigned int refclk_mhz,
406 bool safe_to_lower)
407 {
408 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
409 uint32_t prog_wm_value;
410
411
412 if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
413 > hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) {
414 hubbub1->watermarks.a.cstate_pstate.pstate_change_ns =
415 watermarks->a.cstate_pstate.pstate_change_ns;
416 prog_wm_value = convert_and_clamp(
417 watermarks->a.cstate_pstate.pstate_change_ns,
418 refclk_mhz, 0x1fffff);
419 REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
420 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value,
421 DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
422 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
423 "HW register value = 0x%x\n\n",
424 watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
425 }
426
427
428 if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
429 > hubbub1->watermarks.b.cstate_pstate.pstate_change_ns) {
430 hubbub1->watermarks.b.cstate_pstate.pstate_change_ns =
431 watermarks->b.cstate_pstate.pstate_change_ns;
432 prog_wm_value = convert_and_clamp(
433 watermarks->b.cstate_pstate.pstate_change_ns,
434 refclk_mhz, 0x1fffff);
435 REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
436 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value,
437 DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
438 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
439 "HW register value = 0x%x\n\n",
440 watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
441 }
442
443
444 if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
445 > hubbub1->watermarks.c.cstate_pstate.pstate_change_ns) {
446 hubbub1->watermarks.c.cstate_pstate.pstate_change_ns =
447 watermarks->c.cstate_pstate.pstate_change_ns;
448 prog_wm_value = convert_and_clamp(
449 watermarks->c.cstate_pstate.pstate_change_ns,
450 refclk_mhz, 0x1fffff);
451 REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
452 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value,
453 DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
454 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
455 "HW register value = 0x%x\n\n",
456 watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
457 }
458
459
460 if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
461 > hubbub1->watermarks.d.cstate_pstate.pstate_change_ns) {
462 hubbub1->watermarks.d.cstate_pstate.pstate_change_ns =
463 watermarks->d.cstate_pstate.pstate_change_ns;
464 prog_wm_value = convert_and_clamp(
465 watermarks->d.cstate_pstate.pstate_change_ns,
466 refclk_mhz, 0x1fffff);
467 REG_SET_2(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
468 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value,
469 DCHUBBUB_ARB_VM_ROW_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
470 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
471 "HW register value = 0x%x\n\n",
472 watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
473 }
474 }
475
476 void hubbub21_program_watermarks(
477 struct hubbub *hubbub,
478 struct dcn_watermark_set *watermarks,
479 unsigned int refclk_mhz,
480 bool safe_to_lower)
481 {
482 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
483
484 hubbub21_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
485 hubbub21_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
486 hubbub21_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501 REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
502 DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
503 REG_UPDATE_2(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
504 DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF,
505 DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA);
506 REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL,
507 DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF);
508
509 hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
510 }
511
512 void hubbub21_wm_read_state(struct hubbub *hubbub,
513 struct dcn_hubbub_wm *wm)
514 {
515 struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
516 struct dcn_hubbub_wm_set *s;
517
518 memset(wm, 0, sizeof(struct dcn_hubbub_wm));
519
520 s = &wm->sets[0];
521 s->wm_set = 0;
522 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A,
523 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, &s->data_urgent);
524
525 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A,
526 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, &s->sr_enter);
527
528 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A,
529 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, &s->sr_exit);
530
531 REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A,
532 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, &s->dram_clk_chanage);
533
534 s = &wm->sets[1];
535 s->wm_set = 1;
536 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B,
537 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, &s->data_urgent);
538
539 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B,
540 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, &s->sr_enter);
541
542 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B,
543 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, &s->sr_exit);
544
545 REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B,
546 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, &s->dram_clk_chanage);
547
548 s = &wm->sets[2];
549 s->wm_set = 2;
550 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C,
551 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, &s->data_urgent);
552
553 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C,
554 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, &s->sr_enter);
555
556 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C,
557 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, &s->sr_exit);
558
559 REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C,
560 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, &s->dram_clk_chanage);
561
562 s = &wm->sets[3];
563 s->wm_set = 3;
564 REG_GET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D,
565 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, &s->data_urgent);
566
567 REG_GET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D,
568 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, &s->sr_enter);
569
570 REG_GET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D,
571 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, &s->sr_exit);
572
573 REG_GET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D,
574 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage);
575 }
576
577
578 static const struct hubbub_funcs hubbub21_funcs = {
579 .update_dchub = hubbub2_update_dchub,
580 .init_dchub_sys_ctx = hubbub21_init_dchub,
581 .init_vm_ctx = NULL,
582 .dcc_support_swizzle = hubbub2_dcc_support_swizzle,
583 .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format,
584 .get_dcc_compression_cap = hubbub2_get_dcc_compression_cap,
585 .wm_read_state = hubbub21_wm_read_state,
586 .get_dchub_ref_freq = hubbub2_get_dchub_ref_freq,
587 .program_watermarks = hubbub21_program_watermarks,
588 };
589
590 void hubbub21_construct(struct dcn20_hubbub *hubbub,
591 struct dc_context *ctx,
592 const struct dcn_hubbub_registers *hubbub_regs,
593 const struct dcn_hubbub_shift *hubbub_shift,
594 const struct dcn_hubbub_mask *hubbub_mask)
595 {
596 hubbub->base.ctx = ctx;
597
598 hubbub->base.funcs = &hubbub21_funcs;
599
600 hubbub->regs = hubbub_regs;
601 hubbub->shifts = hubbub_shift;
602 hubbub->masks = hubbub_mask;
603
604 hubbub->debug_test_index_pstate = 0xB;
605 }