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
26
27#include "dcn30/dcn30_hubbub.h"
28#include "dcn31_hubbub.h"
29#include "dm_services.h"
30#include "reg_helper.h"
31
32
33#define CTX \
34 hubbub2->base.ctx
35#define DC_LOGGER \
36 hubbub2->base.ctx->logger
37#define REG(reg)\
38 hubbub2->regs->reg
39
40#undef FN
41#define FN(reg_name, field_name) \
42 hubbub2->shifts->field_name, hubbub2->masks->field_name
43
44#ifdef NUM_VMID
45#undef NUM_VMID
46#endif
47#define NUM_VMID 16
48
49#define DCN31_CRB_SEGMENT_SIZE_KB 64
50
51static void dcn31_init_crb(struct hubbub *hubbub)
52{
53 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
54
55 REG_GET(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT,
56 &hubbub2->det0_size);
57
58 REG_GET(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT,
59 &hubbub2->det1_size);
60
61 REG_GET(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT,
62 &hubbub2->det2_size);
63
64 REG_GET(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT,
65 &hubbub2->det3_size);
66
67 REG_GET(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE_CURRENT,
68 &hubbub2->compbuf_size_segments);
69
70 REG_SET_2(COMPBUF_RESERVED_SPACE, 0,
71 COMPBUF_RESERVED_SPACE_64B, hubbub2->pixel_chunk_size / 32,
72 COMPBUF_RESERVED_SPACE_ZS, hubbub2->pixel_chunk_size / 128);
73 REG_UPDATE(DCHUBBUB_DEBUG_CTRL_0, DET_DEPTH, 0x17F);
74}
75
76static void dcn31_program_det_size(struct hubbub *hubbub, int hubp_inst, unsigned int det_buffer_size_in_kbyte)
77{
78 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
79
80 unsigned int det_size_segments = (det_buffer_size_in_kbyte + DCN31_CRB_SEGMENT_SIZE_KB - 1) / DCN31_CRB_SEGMENT_SIZE_KB;
81
82 switch (hubp_inst) {
83 case 0:
84 REG_UPDATE(DCHUBBUB_DET0_CTRL,
85 DET0_SIZE, det_size_segments);
86 hubbub2->det0_size = det_size_segments;
87 break;
88 case 1:
89 REG_UPDATE(DCHUBBUB_DET1_CTRL,
90 DET1_SIZE, det_size_segments);
91 hubbub2->det1_size = det_size_segments;
92 break;
93 case 2:
94 REG_UPDATE(DCHUBBUB_DET2_CTRL,
95 DET2_SIZE, det_size_segments);
96 hubbub2->det2_size = det_size_segments;
97 break;
98 case 3:
99 REG_UPDATE(DCHUBBUB_DET3_CTRL,
100 DET3_SIZE, det_size_segments);
101 hubbub2->det3_size = det_size_segments;
102 break;
103 default:
104 break;
105 }
106
107 ASSERT(hubbub2->det0_size + hubbub2->det1_size + hubbub2->det2_size
108 + hubbub2->det3_size + hubbub2->compbuf_size_segments <= hubbub2->crb_size_segs);
109}
110
111static void dcn31_program_compbuf_size(struct hubbub *hubbub, unsigned int compbuf_size_kb, bool safe_to_increase)
112{
113 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
114 unsigned int compbuf_size_segments = (compbuf_size_kb + DCN31_CRB_SEGMENT_SIZE_KB - 1) / DCN31_CRB_SEGMENT_SIZE_KB;
115
116 if (safe_to_increase || compbuf_size_segments <= hubbub2->compbuf_size_segments) {
117 if (compbuf_size_segments > hubbub2->compbuf_size_segments) {
118 REG_WAIT(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, hubbub2->det0_size, 1, 100);
119 REG_WAIT(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, hubbub2->det1_size, 1, 100);
120 REG_WAIT(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, hubbub2->det2_size, 1, 100);
121 REG_WAIT(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, hubbub2->det3_size, 1, 100);
122 }
123
124 ASSERT(hubbub2->det0_size + hubbub2->det1_size + hubbub2->det2_size
125 + hubbub2->det3_size + compbuf_size_segments <= hubbub2->crb_size_segs);
126 REG_UPDATE(DCHUBBUB_COMPBUF_CTRL, COMPBUF_SIZE, compbuf_size_segments);
127 hubbub2->compbuf_size_segments = compbuf_size_segments;
128 ASSERT(REG_GET(DCHUBBUB_COMPBUF_CTRL, CONFIG_ERROR, &compbuf_size_segments) && !compbuf_size_segments);
129 }
130}
131
132static uint32_t convert_and_clamp(
133 uint32_t wm_ns,
134 uint32_t refclk_mhz,
135 uint32_t clamp_value)
136{
137 uint32_t ret_val = 0;
138 ret_val = wm_ns * refclk_mhz;
139 ret_val /= 1000;
140
141 if (ret_val > clamp_value)
142 ret_val = clamp_value;
143
144 return ret_val;
145}
146
147static bool hubbub31_program_urgent_watermarks(
148 struct hubbub *hubbub,
149 struct dcn_watermark_set *watermarks,
150 unsigned int refclk_mhz,
151 bool safe_to_lower)
152{
153 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
154 uint32_t prog_wm_value;
155 bool wm_pending = false;
156
157
158
159 if (safe_to_lower || watermarks->a.urgent_ns > hubbub2->watermarks.a.urgent_ns) {
160 hubbub2->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
161 prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
162 refclk_mhz, 0x1fffff);
163 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
164 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
165
166 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
167 "HW register value = 0x%x\n",
168 watermarks->a.urgent_ns, prog_wm_value);
169 } else if (watermarks->a.urgent_ns < hubbub2->watermarks.a.urgent_ns)
170 wm_pending = true;
171
172
173 if (safe_to_lower || watermarks->a.frac_urg_bw_flip
174 > hubbub2->watermarks.a.frac_urg_bw_flip) {
175 hubbub2->watermarks.a.frac_urg_bw_flip = watermarks->a.frac_urg_bw_flip;
176
177 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0,
178 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip);
179 } else if (watermarks->a.frac_urg_bw_flip
180 < hubbub2->watermarks.a.frac_urg_bw_flip)
181 wm_pending = true;
182
183 if (safe_to_lower || watermarks->a.frac_urg_bw_nom
184 > hubbub2->watermarks.a.frac_urg_bw_nom) {
185 hubbub2->watermarks.a.frac_urg_bw_nom = watermarks->a.frac_urg_bw_nom;
186
187 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
188 DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom);
189 } else if (watermarks->a.frac_urg_bw_nom
190 < hubbub2->watermarks.a.frac_urg_bw_nom)
191 wm_pending = true;
192
193 if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub2->watermarks.a.urgent_latency_ns) {
194 hubbub2->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns;
195 prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns,
196 refclk_mhz, 0x1fffff);
197 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
198 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value);
199 } else if (watermarks->a.urgent_latency_ns < hubbub2->watermarks.a.urgent_latency_ns)
200 wm_pending = true;
201
202
203 if (safe_to_lower || watermarks->b.urgent_ns > hubbub2->watermarks.b.urgent_ns) {
204 hubbub2->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
205 prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
206 refclk_mhz, 0x1fffff);
207 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
208 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
209
210 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
211 "HW register value = 0x%x\n",
212 watermarks->b.urgent_ns, prog_wm_value);
213 } else if (watermarks->b.urgent_ns < hubbub2->watermarks.b.urgent_ns)
214 wm_pending = true;
215
216
217 if (safe_to_lower || watermarks->b.frac_urg_bw_flip
218 > hubbub2->watermarks.b.frac_urg_bw_flip) {
219 hubbub2->watermarks.b.frac_urg_bw_flip = watermarks->b.frac_urg_bw_flip;
220
221 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0,
222 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->b.frac_urg_bw_flip);
223 } else if (watermarks->b.frac_urg_bw_flip
224 < hubbub2->watermarks.b.frac_urg_bw_flip)
225 wm_pending = true;
226
227 if (safe_to_lower || watermarks->b.frac_urg_bw_nom
228 > hubbub2->watermarks.b.frac_urg_bw_nom) {
229 hubbub2->watermarks.b.frac_urg_bw_nom = watermarks->b.frac_urg_bw_nom;
230
231 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0,
232 DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->b.frac_urg_bw_nom);
233 } else if (watermarks->b.frac_urg_bw_nom
234 < hubbub2->watermarks.b.frac_urg_bw_nom)
235 wm_pending = true;
236
237 if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub2->watermarks.b.urgent_latency_ns) {
238 hubbub2->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns;
239 prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns,
240 refclk_mhz, 0x1fffff);
241 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
242 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value);
243 } else if (watermarks->b.urgent_latency_ns < hubbub2->watermarks.b.urgent_latency_ns)
244 wm_pending = true;
245
246
247 if (safe_to_lower || watermarks->c.urgent_ns > hubbub2->watermarks.c.urgent_ns) {
248 hubbub2->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
249 prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
250 refclk_mhz, 0x1fffff);
251 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
252 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
253
254 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
255 "HW register value = 0x%x\n",
256 watermarks->c.urgent_ns, prog_wm_value);
257 } else if (watermarks->c.urgent_ns < hubbub2->watermarks.c.urgent_ns)
258 wm_pending = true;
259
260
261 if (safe_to_lower || watermarks->c.frac_urg_bw_flip
262 > hubbub2->watermarks.c.frac_urg_bw_flip) {
263 hubbub2->watermarks.c.frac_urg_bw_flip = watermarks->c.frac_urg_bw_flip;
264
265 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0,
266 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->c.frac_urg_bw_flip);
267 } else if (watermarks->c.frac_urg_bw_flip
268 < hubbub2->watermarks.c.frac_urg_bw_flip)
269 wm_pending = true;
270
271 if (safe_to_lower || watermarks->c.frac_urg_bw_nom
272 > hubbub2->watermarks.c.frac_urg_bw_nom) {
273 hubbub2->watermarks.c.frac_urg_bw_nom = watermarks->c.frac_urg_bw_nom;
274
275 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0,
276 DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->c.frac_urg_bw_nom);
277 } else if (watermarks->c.frac_urg_bw_nom
278 < hubbub2->watermarks.c.frac_urg_bw_nom)
279 wm_pending = true;
280
281 if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub2->watermarks.c.urgent_latency_ns) {
282 hubbub2->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns;
283 prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns,
284 refclk_mhz, 0x1fffff);
285 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0,
286 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value);
287 } else if (watermarks->c.urgent_latency_ns < hubbub2->watermarks.c.urgent_latency_ns)
288 wm_pending = true;
289
290
291 if (safe_to_lower || watermarks->d.urgent_ns > hubbub2->watermarks.d.urgent_ns) {
292 hubbub2->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
293 prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
294 refclk_mhz, 0x1fffff);
295 REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
296 DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
297
298 DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
299 "HW register value = 0x%x\n",
300 watermarks->d.urgent_ns, prog_wm_value);
301 } else if (watermarks->d.urgent_ns < hubbub2->watermarks.d.urgent_ns)
302 wm_pending = true;
303
304
305 if (safe_to_lower || watermarks->d.frac_urg_bw_flip
306 > hubbub2->watermarks.d.frac_urg_bw_flip) {
307 hubbub2->watermarks.d.frac_urg_bw_flip = watermarks->d.frac_urg_bw_flip;
308
309 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0,
310 DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->d.frac_urg_bw_flip);
311 } else if (watermarks->d.frac_urg_bw_flip
312 < hubbub2->watermarks.d.frac_urg_bw_flip)
313 wm_pending = true;
314
315 if (safe_to_lower || watermarks->d.frac_urg_bw_nom
316 > hubbub2->watermarks.d.frac_urg_bw_nom) {
317 hubbub2->watermarks.d.frac_urg_bw_nom = watermarks->d.frac_urg_bw_nom;
318
319 REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0,
320 DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->d.frac_urg_bw_nom);
321 } else if (watermarks->d.frac_urg_bw_nom
322 < hubbub2->watermarks.d.frac_urg_bw_nom)
323 wm_pending = true;
324
325 if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub2->watermarks.d.urgent_latency_ns) {
326 hubbub2->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns;
327 prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns,
328 refclk_mhz, 0x1fffff);
329 REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0,
330 DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value);
331 } else if (watermarks->d.urgent_latency_ns < hubbub2->watermarks.d.urgent_latency_ns)
332 wm_pending = true;
333
334 return wm_pending;
335}
336
337static bool hubbub31_program_stutter_watermarks(
338 struct hubbub *hubbub,
339 struct dcn_watermark_set *watermarks,
340 unsigned int refclk_mhz,
341 bool safe_to_lower)
342{
343 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
344 uint32_t prog_wm_value;
345 bool wm_pending = false;
346
347
348 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
349 > hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) {
350 hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
351 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns;
352 prog_wm_value = convert_and_clamp(
353 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns,
354 refclk_mhz, 0x1fffff);
355 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
356 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
357 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
358 "HW register value = 0x%x\n",
359 watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
360 } else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
361 < hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns)
362 wm_pending = true;
363
364 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
365 > hubbub2->watermarks.a.cstate_pstate.cstate_exit_ns) {
366 hubbub2->watermarks.a.cstate_pstate.cstate_exit_ns =
367 watermarks->a.cstate_pstate.cstate_exit_ns;
368 prog_wm_value = convert_and_clamp(
369 watermarks->a.cstate_pstate.cstate_exit_ns,
370 refclk_mhz, 0x1fffff);
371 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
372 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
373 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
374 "HW register value = 0x%x\n",
375 watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
376 } else if (watermarks->a.cstate_pstate.cstate_exit_ns
377 < hubbub2->watermarks.a.cstate_pstate.cstate_exit_ns)
378 wm_pending = true;
379
380 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns
381 > hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns) {
382 hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns =
383 watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns;
384 prog_wm_value = convert_and_clamp(
385 watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns,
386 refclk_mhz, 0x1fffff);
387 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, 0,
388 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, prog_wm_value);
389 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_A calculated =%d\n"
390 "HW register value = 0x%x\n",
391 watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);
392 } else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns
393 < hubbub2->watermarks.a.cstate_pstate.cstate_enter_plus_exit_z8_ns)
394 wm_pending = true;
395
396 if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_z8_ns
397 > hubbub2->watermarks.a.cstate_pstate.cstate_exit_z8_ns) {
398 hubbub2->watermarks.a.cstate_pstate.cstate_exit_z8_ns =
399 watermarks->a.cstate_pstate.cstate_exit_z8_ns;
400 prog_wm_value = convert_and_clamp(
401 watermarks->a.cstate_pstate.cstate_exit_z8_ns,
402 refclk_mhz, 0x1fffff);
403 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, 0,
404 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, prog_wm_value);
405 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_A calculated =%d\n"
406 "HW register value = 0x%x\n",
407 watermarks->a.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);
408 } else if (watermarks->a.cstate_pstate.cstate_exit_z8_ns
409 < hubbub2->watermarks.a.cstate_pstate.cstate_exit_z8_ns)
410 wm_pending = true;
411
412
413 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
414 > hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) {
415 hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
416 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns;
417 prog_wm_value = convert_and_clamp(
418 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns,
419 refclk_mhz, 0x1fffff);
420 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
421 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
422 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
423 "HW register value = 0x%x\n",
424 watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
425 } else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
426 < hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns)
427 wm_pending = true;
428
429 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
430 > hubbub2->watermarks.b.cstate_pstate.cstate_exit_ns) {
431 hubbub2->watermarks.b.cstate_pstate.cstate_exit_ns =
432 watermarks->b.cstate_pstate.cstate_exit_ns;
433 prog_wm_value = convert_and_clamp(
434 watermarks->b.cstate_pstate.cstate_exit_ns,
435 refclk_mhz, 0x1fffff);
436 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
437 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
438 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
439 "HW register value = 0x%x\n",
440 watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
441 } else if (watermarks->b.cstate_pstate.cstate_exit_ns
442 < hubbub2->watermarks.b.cstate_pstate.cstate_exit_ns)
443 wm_pending = true;
444
445 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns
446 > hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_z8_ns) {
447 hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_z8_ns =
448 watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns;
449 prog_wm_value = convert_and_clamp(
450 watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns,
451 refclk_mhz, 0x1fffff);
452 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, 0,
453 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, prog_wm_value);
454 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_B calculated =%d\n"
455 "HW register value = 0x%x\n",
456 watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);
457 } else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns
458 < hubbub2->watermarks.b.cstate_pstate.cstate_enter_plus_exit_z8_ns)
459 wm_pending = true;
460
461 if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_z8_ns
462 > hubbub2->watermarks.b.cstate_pstate.cstate_exit_z8_ns) {
463 hubbub2->watermarks.b.cstate_pstate.cstate_exit_z8_ns =
464 watermarks->b.cstate_pstate.cstate_exit_z8_ns;
465 prog_wm_value = convert_and_clamp(
466 watermarks->b.cstate_pstate.cstate_exit_z8_ns,
467 refclk_mhz, 0x1fffff);
468 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, 0,
469 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, prog_wm_value);
470 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_B calculated =%d\n"
471 "HW register value = 0x%x\n",
472 watermarks->b.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);
473 } else if (watermarks->b.cstate_pstate.cstate_exit_z8_ns
474 < hubbub2->watermarks.b.cstate_pstate.cstate_exit_z8_ns)
475 wm_pending = true;
476
477
478 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
479 > hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) {
480 hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
481 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns;
482 prog_wm_value = convert_and_clamp(
483 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns,
484 refclk_mhz, 0x1fffff);
485 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
486 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
487 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
488 "HW register value = 0x%x\n",
489 watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
490 } else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
491 < hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns)
492 wm_pending = true;
493
494 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
495 > hubbub2->watermarks.c.cstate_pstate.cstate_exit_ns) {
496 hubbub2->watermarks.c.cstate_pstate.cstate_exit_ns =
497 watermarks->c.cstate_pstate.cstate_exit_ns;
498 prog_wm_value = convert_and_clamp(
499 watermarks->c.cstate_pstate.cstate_exit_ns,
500 refclk_mhz, 0x1fffff);
501 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
502 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
503 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
504 "HW register value = 0x%x\n",
505 watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
506 } else if (watermarks->c.cstate_pstate.cstate_exit_ns
507 < hubbub2->watermarks.c.cstate_pstate.cstate_exit_ns)
508 wm_pending = true;
509
510 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns
511 > hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_z8_ns) {
512 hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_z8_ns =
513 watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns;
514 prog_wm_value = convert_and_clamp(
515 watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns,
516 refclk_mhz, 0x1fffff);
517 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, 0,
518 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, prog_wm_value);
519 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_C calculated =%d\n"
520 "HW register value = 0x%x\n",
521 watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);
522 } else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns
523 < hubbub2->watermarks.c.cstate_pstate.cstate_enter_plus_exit_z8_ns)
524 wm_pending = true;
525
526 if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_z8_ns
527 > hubbub2->watermarks.c.cstate_pstate.cstate_exit_z8_ns) {
528 hubbub2->watermarks.c.cstate_pstate.cstate_exit_z8_ns =
529 watermarks->c.cstate_pstate.cstate_exit_z8_ns;
530 prog_wm_value = convert_and_clamp(
531 watermarks->c.cstate_pstate.cstate_exit_z8_ns,
532 refclk_mhz, 0x1fffff);
533 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, 0,
534 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, prog_wm_value);
535 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_C calculated =%d\n"
536 "HW register value = 0x%x\n",
537 watermarks->c.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);
538 } else if (watermarks->c.cstate_pstate.cstate_exit_z8_ns
539 < hubbub2->watermarks.c.cstate_pstate.cstate_exit_z8_ns)
540 wm_pending = true;
541
542
543 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
544 > hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) {
545 hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
546 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns;
547 prog_wm_value = convert_and_clamp(
548 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns,
549 refclk_mhz, 0x1fffff);
550 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
551 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
552 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
553 "HW register value = 0x%x\n",
554 watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
555 } else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
556 < hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns)
557 wm_pending = true;
558
559 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
560 > hubbub2->watermarks.d.cstate_pstate.cstate_exit_ns) {
561 hubbub2->watermarks.d.cstate_pstate.cstate_exit_ns =
562 watermarks->d.cstate_pstate.cstate_exit_ns;
563 prog_wm_value = convert_and_clamp(
564 watermarks->d.cstate_pstate.cstate_exit_ns,
565 refclk_mhz, 0x1fffff);
566 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
567 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
568 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
569 "HW register value = 0x%x\n",
570 watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
571 } else if (watermarks->d.cstate_pstate.cstate_exit_ns
572 < hubbub2->watermarks.d.cstate_pstate.cstate_exit_ns)
573 wm_pending = true;
574
575 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns
576 > hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_z8_ns) {
577 hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_z8_ns =
578 watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns;
579 prog_wm_value = convert_and_clamp(
580 watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns,
581 refclk_mhz, 0x1fffff);
582 REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, 0,
583 DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, prog_wm_value);
584 DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_D calculated =%d\n"
585 "HW register value = 0x%x\n",
586 watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns, prog_wm_value);
587 } else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns
588 < hubbub2->watermarks.d.cstate_pstate.cstate_enter_plus_exit_z8_ns)
589 wm_pending = true;
590
591 if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_z8_ns
592 > hubbub2->watermarks.d.cstate_pstate.cstate_exit_z8_ns) {
593 hubbub2->watermarks.d.cstate_pstate.cstate_exit_z8_ns =
594 watermarks->d.cstate_pstate.cstate_exit_z8_ns;
595 prog_wm_value = convert_and_clamp(
596 watermarks->d.cstate_pstate.cstate_exit_z8_ns,
597 refclk_mhz, 0x1fffff);
598 REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, 0,
599 DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, prog_wm_value);
600 DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_D calculated =%d\n"
601 "HW register value = 0x%x\n",
602 watermarks->d.cstate_pstate.cstate_exit_z8_ns, prog_wm_value);
603 } else if (watermarks->d.cstate_pstate.cstate_exit_z8_ns
604 < hubbub2->watermarks.d.cstate_pstate.cstate_exit_z8_ns)
605 wm_pending = true;
606
607 return wm_pending;
608}
609
610static bool hubbub31_program_pstate_watermarks(
611 struct hubbub *hubbub,
612 struct dcn_watermark_set *watermarks,
613 unsigned int refclk_mhz,
614 bool safe_to_lower)
615{
616 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
617 uint32_t prog_wm_value;
618
619 bool wm_pending = false;
620
621
622 if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
623 > hubbub2->watermarks.a.cstate_pstate.pstate_change_ns) {
624 hubbub2->watermarks.a.cstate_pstate.pstate_change_ns =
625 watermarks->a.cstate_pstate.pstate_change_ns;
626 prog_wm_value = convert_and_clamp(
627 watermarks->a.cstate_pstate.pstate_change_ns,
628 refclk_mhz, 0x1fffff);
629 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
630 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
631 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
632 "HW register value = 0x%x\n\n",
633 watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
634 } else if (watermarks->a.cstate_pstate.pstate_change_ns
635 < hubbub2->watermarks.a.cstate_pstate.pstate_change_ns)
636 wm_pending = true;
637
638
639 if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
640 > hubbub2->watermarks.b.cstate_pstate.pstate_change_ns) {
641 hubbub2->watermarks.b.cstate_pstate.pstate_change_ns =
642 watermarks->b.cstate_pstate.pstate_change_ns;
643 prog_wm_value = convert_and_clamp(
644 watermarks->b.cstate_pstate.pstate_change_ns,
645 refclk_mhz, 0x1fffff);
646 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
647 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
648 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
649 "HW register value = 0x%x\n\n",
650 watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
651 } else if (watermarks->b.cstate_pstate.pstate_change_ns
652 < hubbub2->watermarks.b.cstate_pstate.pstate_change_ns)
653 wm_pending = false;
654
655
656 if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
657 > hubbub2->watermarks.c.cstate_pstate.pstate_change_ns) {
658 hubbub2->watermarks.c.cstate_pstate.pstate_change_ns =
659 watermarks->c.cstate_pstate.pstate_change_ns;
660 prog_wm_value = convert_and_clamp(
661 watermarks->c.cstate_pstate.pstate_change_ns,
662 refclk_mhz, 0x1fffff);
663 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
664 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
665 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
666 "HW register value = 0x%x\n\n",
667 watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
668 } else if (watermarks->c.cstate_pstate.pstate_change_ns
669 < hubbub2->watermarks.c.cstate_pstate.pstate_change_ns)
670 wm_pending = true;
671
672
673 if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
674 > hubbub2->watermarks.d.cstate_pstate.pstate_change_ns) {
675 hubbub2->watermarks.d.cstate_pstate.pstate_change_ns =
676 watermarks->d.cstate_pstate.pstate_change_ns;
677 prog_wm_value = convert_and_clamp(
678 watermarks->d.cstate_pstate.pstate_change_ns,
679 refclk_mhz, 0x1fffff);
680 REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
681 DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
682 DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
683 "HW register value = 0x%x\n\n",
684 watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
685 } else if (watermarks->d.cstate_pstate.pstate_change_ns
686 < hubbub2->watermarks.d.cstate_pstate.pstate_change_ns)
687 wm_pending = true;
688
689 return wm_pending;
690}
691
692static bool hubbub31_program_watermarks(
693 struct hubbub *hubbub,
694 struct dcn_watermark_set *watermarks,
695 unsigned int refclk_mhz,
696 bool safe_to_lower)
697{
698 bool wm_pending = false;
699
700 if (hubbub31_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
701 wm_pending = true;
702
703 if (hubbub31_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
704 wm_pending = true;
705
706 if (hubbub31_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
707 wm_pending = true;
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727 hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
728 return wm_pending;
729}
730
731static void hubbub3_get_blk256_size(unsigned int *blk256_width, unsigned int *blk256_height,
732 unsigned int bytes_per_element)
733{
734
735
736 if (bytes_per_element == 1) {
737 *blk256_width = 16;
738 *blk256_height = 16;
739 } else if (bytes_per_element == 2) {
740 *blk256_width = 16;
741 *blk256_height = 8;
742 } else if (bytes_per_element == 4) {
743 *blk256_width = 8;
744 *blk256_height = 8;
745 } else if (bytes_per_element == 8) {
746 *blk256_width = 8;
747 *blk256_height = 4;
748 }
749}
750
751static void hubbub31_det_request_size(
752 unsigned int detile_buf_size,
753 unsigned int height,
754 unsigned int width,
755 unsigned int bpe,
756 bool *req128_horz_wc,
757 bool *req128_vert_wc)
758{
759 unsigned int blk256_height = 0;
760 unsigned int blk256_width = 0;
761 unsigned int swath_bytes_horz_wc, swath_bytes_vert_wc;
762
763 hubbub3_get_blk256_size(&blk256_width, &blk256_height, bpe);
764
765 swath_bytes_horz_wc = width * blk256_height * bpe;
766 swath_bytes_vert_wc = height * blk256_width * bpe;
767
768 *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ?
769 false :
770 true;
771
772 *req128_vert_wc = (2 * swath_bytes_vert_wc <= detile_buf_size) ?
773 false :
774 true;
775}
776
777static bool hubbub31_get_dcc_compression_cap(struct hubbub *hubbub,
778 const struct dc_dcc_surface_param *input,
779 struct dc_surface_dcc_cap *output)
780{
781 struct dc *dc = hubbub->ctx->dc;
782 enum dcc_control dcc_control;
783 unsigned int bpe;
784 enum segment_order segment_order_horz, segment_order_vert;
785 bool req128_horz_wc, req128_vert_wc;
786
787 memset(output, 0, sizeof(*output));
788
789 if (dc->debug.disable_dcc == DCC_DISABLE)
790 return false;
791
792 if (!hubbub->funcs->dcc_support_pixel_format(input->format,
793 &bpe))
794 return false;
795
796 if (!hubbub->funcs->dcc_support_swizzle(input->swizzle_mode, bpe,
797 &segment_order_horz, &segment_order_vert))
798 return false;
799
800 hubbub31_det_request_size(TO_DCN20_HUBBUB(hubbub)->detile_buf_size,
801 input->surface_size.height, input->surface_size.width,
802 bpe, &req128_horz_wc, &req128_vert_wc);
803
804 if (!req128_horz_wc && !req128_vert_wc) {
805 dcc_control = dcc_control__256_256_xxx;
806 } else if (input->scan == SCAN_DIRECTION_HORIZONTAL) {
807 if (!req128_horz_wc)
808 dcc_control = dcc_control__256_256_xxx;
809 else if (segment_order_horz == segment_order__contiguous)
810 dcc_control = dcc_control__128_128_xxx;
811 else
812 dcc_control = dcc_control__256_64_64;
813 } else if (input->scan == SCAN_DIRECTION_VERTICAL) {
814 if (!req128_vert_wc)
815 dcc_control = dcc_control__256_256_xxx;
816 else if (segment_order_vert == segment_order__contiguous)
817 dcc_control = dcc_control__128_128_xxx;
818 else
819 dcc_control = dcc_control__256_64_64;
820 } else {
821 if ((req128_horz_wc &&
822 segment_order_horz == segment_order__non_contiguous) ||
823 (req128_vert_wc &&
824 segment_order_vert == segment_order__non_contiguous))
825
826 dcc_control = dcc_control__256_64_64;
827 else
828
829
830
831 dcc_control = dcc_control__128_128_xxx;
832 }
833
834
835 if ((bpe == 2) && (input->swizzle_mode == DC_SW_64KB_R_X))
836 dcc_control = dcc_control__128_128_xxx;
837
838 if (dc->debug.disable_dcc == DCC_HALF_REQ_DISALBE &&
839 dcc_control != dcc_control__256_256_xxx)
840 return false;
841
842 switch (dcc_control) {
843 case dcc_control__256_256_xxx:
844 output->grph.rgb.max_uncompressed_blk_size = 256;
845 output->grph.rgb.max_compressed_blk_size = 256;
846 output->grph.rgb.independent_64b_blks = false;
847 output->grph.rgb.dcc_controls.dcc_256_256_unconstrained = 1;
848 output->grph.rgb.dcc_controls.dcc_256_128_128 = 1;
849 break;
850 case dcc_control__128_128_xxx:
851 output->grph.rgb.max_uncompressed_blk_size = 128;
852 output->grph.rgb.max_compressed_blk_size = 128;
853 output->grph.rgb.independent_64b_blks = false;
854 output->grph.rgb.dcc_controls.dcc_128_128_uncontrained = 1;
855 output->grph.rgb.dcc_controls.dcc_256_128_128 = 1;
856 break;
857 case dcc_control__256_64_64:
858 output->grph.rgb.max_uncompressed_blk_size = 256;
859 output->grph.rgb.max_compressed_blk_size = 64;
860 output->grph.rgb.independent_64b_blks = true;
861 output->grph.rgb.dcc_controls.dcc_256_64_64 = 1;
862 break;
863 case dcc_control__256_128_128:
864 output->grph.rgb.max_uncompressed_blk_size = 256;
865 output->grph.rgb.max_compressed_blk_size = 128;
866 output->grph.rgb.independent_64b_blks = false;
867 output->grph.rgb.dcc_controls.dcc_256_128_128 = 1;
868 break;
869 }
870 output->capable = true;
871 output->const_color_support = true;
872
873 return true;
874}
875
876static int hubbub31_init_dchub_sys_ctx(struct hubbub *hubbub,
877 struct dcn_hubbub_phys_addr_config *pa_config)
878{
879 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
880 struct dcn_vmid_page_table_config phys_config;
881
882 REG_SET(DCN_VM_FB_LOCATION_BASE, 0,
883 FB_BASE, pa_config->system_aperture.fb_base >> 24);
884 REG_SET(DCN_VM_FB_LOCATION_TOP, 0,
885 FB_TOP, pa_config->system_aperture.fb_top >> 24);
886 REG_SET(DCN_VM_FB_OFFSET, 0,
887 FB_OFFSET, pa_config->system_aperture.fb_offset >> 24);
888 REG_SET(DCN_VM_AGP_BOT, 0,
889 AGP_BOT, pa_config->system_aperture.agp_bot >> 24);
890 REG_SET(DCN_VM_AGP_TOP, 0,
891 AGP_TOP, pa_config->system_aperture.agp_top >> 24);
892 REG_SET(DCN_VM_AGP_BASE, 0,
893 AGP_BASE, pa_config->system_aperture.agp_base >> 24);
894
895 if (pa_config->gart_config.page_table_start_addr != pa_config->gart_config.page_table_end_addr) {
896 phys_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr >> 12;
897 phys_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr >> 12;
898 phys_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;
899 phys_config.depth = 0;
900 phys_config.block_size = 0;
901
902 dcn20_vmid_setup(&hubbub2->vmid[0], &phys_config);
903
904 dcn20_vmid_setup(&hubbub2->vmid[15], &phys_config);
905 }
906
907 dcn21_dchvm_init(hubbub);
908
909 return NUM_VMID;
910}
911
912static void hubbub31_get_dchub_ref_freq(struct hubbub *hubbub,
913 unsigned int dccg_ref_freq_inKhz,
914 unsigned int *dchub_ref_freq_inKhz)
915{
916 struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
917 uint32_t ref_div = 0;
918 uint32_t ref_en = 0;
919 unsigned int dc_refclk_khz = 24000;
920
921 REG_GET_2(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, &ref_div,
922 DCHUBBUB_GLOBAL_TIMER_ENABLE, &ref_en);
923
924 if (ref_en) {
925 if (ref_div == 2)
926 *dchub_ref_freq_inKhz = dc_refclk_khz / 2;
927 else
928 *dchub_ref_freq_inKhz = dc_refclk_khz;
929
930
931
932
933
934
935
936 if (*dchub_ref_freq_inKhz < 20000 || *dchub_ref_freq_inKhz > 50000)
937 ASSERT_CRITICAL(false);
938
939 return;
940 } else {
941 *dchub_ref_freq_inKhz = dc_refclk_khz;
942
943
944 ASSERT_CRITICAL(false);
945 return;
946 }
947}
948
949static const struct hubbub_funcs hubbub31_funcs = {
950 .update_dchub = hubbub2_update_dchub,
951 .init_dchub_sys_ctx = hubbub31_init_dchub_sys_ctx,
952 .init_vm_ctx = hubbub2_init_vm_ctx,
953 .dcc_support_swizzle = hubbub3_dcc_support_swizzle,
954 .dcc_support_pixel_format = hubbub2_dcc_support_pixel_format,
955 .get_dcc_compression_cap = hubbub31_get_dcc_compression_cap,
956 .wm_read_state = hubbub21_wm_read_state,
957 .get_dchub_ref_freq = hubbub31_get_dchub_ref_freq,
958 .program_watermarks = hubbub31_program_watermarks,
959 .allow_self_refresh_control = hubbub1_allow_self_refresh_control,
960 .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
961 .program_det_size = dcn31_program_det_size,
962 .program_compbuf_size = dcn31_program_compbuf_size,
963 .init_crb = dcn31_init_crb,
964 .hubbub_read_state = hubbub2_read_state,
965};
966
967void hubbub31_construct(struct dcn20_hubbub *hubbub31,
968 struct dc_context *ctx,
969 const struct dcn_hubbub_registers *hubbub_regs,
970 const struct dcn_hubbub_shift *hubbub_shift,
971 const struct dcn_hubbub_mask *hubbub_mask,
972 int det_size_kb,
973 int pixel_chunk_size_kb,
974 int config_return_buffer_size_kb)
975{
976
977 hubbub3_construct(hubbub31, ctx, hubbub_regs, hubbub_shift, hubbub_mask);
978 hubbub31->base.funcs = &hubbub31_funcs;
979 hubbub31->detile_buf_size = det_size_kb * 1024;
980 hubbub31->pixel_chunk_size = pixel_chunk_size_kb * 1024;
981 hubbub31->crb_size_segs = config_return_buffer_size_kb / DCN31_CRB_SEGMENT_SIZE_KB;
982}
983
984