2 * Copyright 2016 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
27 #include "dcn20_hubbub.h"
28 #include "reg_helper.h"
38 #define FN(reg_name, field_name) \
39 hubbub1->shifts->field_name, hubbub1->masks->field_name
48 #define FN(reg_name, field_name) \
49 hubbub1->shifts->field_name, hubbub1->masks->field_name
56 bool hubbub2_dcc_support_swizzle(
57 enum swizzle_mode_values swizzle
,
58 unsigned int bytes_per_element
,
59 enum segment_order
*segment_order_horz
,
60 enum segment_order
*segment_order_vert
)
62 bool standard_swizzle
= false;
63 bool display_swizzle
= false;
64 bool render_swizzle
= false;
73 standard_swizzle
= true;
76 render_swizzle
= true;
84 display_swizzle
= true;
90 if (standard_swizzle
) {
91 if (bytes_per_element
== 1) {
92 *segment_order_horz
= segment_order__contiguous
;
93 *segment_order_vert
= segment_order__na
;
96 if (bytes_per_element
== 2) {
97 *segment_order_horz
= segment_order__non_contiguous
;
98 *segment_order_vert
= segment_order__contiguous
;
101 if (bytes_per_element
== 4) {
102 *segment_order_horz
= segment_order__non_contiguous
;
103 *segment_order_vert
= segment_order__contiguous
;
106 if (bytes_per_element
== 8) {
107 *segment_order_horz
= segment_order__na
;
108 *segment_order_vert
= segment_order__contiguous
;
112 if (render_swizzle
) {
113 if (bytes_per_element
== 2) {
114 *segment_order_horz
= segment_order__contiguous
;
115 *segment_order_vert
= segment_order__contiguous
;
118 if (bytes_per_element
== 4) {
119 *segment_order_horz
= segment_order__non_contiguous
;
120 *segment_order_vert
= segment_order__contiguous
;
123 if (bytes_per_element
== 8) {
124 *segment_order_horz
= segment_order__contiguous
;
125 *segment_order_vert
= segment_order__non_contiguous
;
129 if (display_swizzle
&& bytes_per_element
== 8) {
130 *segment_order_horz
= segment_order__contiguous
;
131 *segment_order_vert
= segment_order__non_contiguous
;
138 bool hubbub2_dcc_support_pixel_format(
139 enum surface_pixel_format format
,
140 unsigned int *bytes_per_element
)
142 /* DML: get_bytes_per_element */
144 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555
:
145 case SURFACE_PIXEL_FORMAT_GRPH_RGB565
:
146 *bytes_per_element
= 2;
148 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888
:
149 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
:
150 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010
:
151 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
:
152 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX
:
153 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX
:
154 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT
:
155 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT
:
156 *bytes_per_element
= 4;
158 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616
:
159 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F
:
160 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
:
161 *bytes_per_element
= 8;
168 static void hubbub2_get_blk256_size(unsigned int *blk256_width
, unsigned int *blk256_height
,
169 unsigned int bytes_per_element
)
171 /* copied from DML. might want to refactor DML to leverage from DML */
172 /* DML : get_blk256_size */
173 if (bytes_per_element
== 1) {
176 } else if (bytes_per_element
== 2) {
179 } else if (bytes_per_element
== 4) {
182 } else if (bytes_per_element
== 8) {
188 static void hubbub2_det_request_size(
189 unsigned int detile_buf_size
,
193 bool *req128_horz_wc
,
194 bool *req128_vert_wc
)
196 unsigned int blk256_height
= 0;
197 unsigned int blk256_width
= 0;
198 unsigned int swath_bytes_horz_wc
, swath_bytes_vert_wc
;
200 hubbub2_get_blk256_size(&blk256_width
, &blk256_height
, bpe
);
202 swath_bytes_horz_wc
= width
* blk256_height
* bpe
;
203 swath_bytes_vert_wc
= height
* blk256_width
* bpe
;
205 *req128_horz_wc
= (2 * swath_bytes_horz_wc
<= detile_buf_size
) ?
206 false : /* full 256B request */
207 true; /* half 128b request */
209 *req128_vert_wc
= (2 * swath_bytes_vert_wc
<= detile_buf_size
) ?
210 false : /* full 256B request */
211 true; /* half 128b request */
214 bool hubbub2_get_dcc_compression_cap(struct hubbub
*hubbub
,
215 const struct dc_dcc_surface_param
*input
,
216 struct dc_surface_dcc_cap
*output
)
218 struct dc
*dc
= hubbub
->ctx
->dc
;
219 /* implement section 1.6.2.1 of DCN1_Programming_Guide.docx */
220 enum dcc_control dcc_control
;
222 enum segment_order segment_order_horz
, segment_order_vert
;
223 bool req128_horz_wc
, req128_vert_wc
;
225 memset(output
, 0, sizeof(*output
));
227 if (dc
->debug
.disable_dcc
== DCC_DISABLE
)
230 if (!hubbub
->funcs
->dcc_support_pixel_format(input
->format
,
234 if (!hubbub
->funcs
->dcc_support_swizzle(input
->swizzle_mode
, bpe
,
235 &segment_order_horz
, &segment_order_vert
))
238 hubbub2_det_request_size(TO_DCN20_HUBBUB(hubbub
)->detile_buf_size
,
239 input
->surface_size
.height
, input
->surface_size
.width
,
240 bpe
, &req128_horz_wc
, &req128_vert_wc
);
242 if (!req128_horz_wc
&& !req128_vert_wc
) {
243 dcc_control
= dcc_control__256_256_xxx
;
244 } else if (input
->scan
== SCAN_DIRECTION_HORIZONTAL
) {
246 dcc_control
= dcc_control__256_256_xxx
;
247 else if (segment_order_horz
== segment_order__contiguous
)
248 dcc_control
= dcc_control__128_128_xxx
;
250 dcc_control
= dcc_control__256_64_64
;
251 } else if (input
->scan
== SCAN_DIRECTION_VERTICAL
) {
253 dcc_control
= dcc_control__256_256_xxx
;
254 else if (segment_order_vert
== segment_order__contiguous
)
255 dcc_control
= dcc_control__128_128_xxx
;
257 dcc_control
= dcc_control__256_64_64
;
259 if ((req128_horz_wc
&&
260 segment_order_horz
== segment_order__non_contiguous
) ||
262 segment_order_vert
== segment_order__non_contiguous
))
263 /* access_dir not known, must use most constraining */
264 dcc_control
= dcc_control__256_64_64
;
266 /* reg128 is true for either horz and vert
267 * but segment_order is contiguous
269 dcc_control
= dcc_control__128_128_xxx
;
272 /* Exception for 64KB_R_X */
273 if ((bpe
== 2) && (input
->swizzle_mode
== DC_SW_64KB_R_X
))
274 dcc_control
= dcc_control__128_128_xxx
;
276 if (dc
->debug
.disable_dcc
== DCC_HALF_REQ_DISALBE
&&
277 dcc_control
!= dcc_control__256_256_xxx
)
280 switch (dcc_control
) {
281 case dcc_control__256_256_xxx
:
282 output
->grph
.rgb
.max_uncompressed_blk_size
= 256;
283 output
->grph
.rgb
.max_compressed_blk_size
= 256;
284 output
->grph
.rgb
.independent_64b_blks
= false;
286 case dcc_control__128_128_xxx
:
287 output
->grph
.rgb
.max_uncompressed_blk_size
= 128;
288 output
->grph
.rgb
.max_compressed_blk_size
= 128;
289 output
->grph
.rgb
.independent_64b_blks
= false;
291 case dcc_control__256_64_64
:
292 output
->grph
.rgb
.max_uncompressed_blk_size
= 256;
293 output
->grph
.rgb
.max_compressed_blk_size
= 64;
294 output
->grph
.rgb
.independent_64b_blks
= true;
300 output
->capable
= true;
301 output
->const_color_support
= true;
306 static enum dcn_hubbub_page_table_depth
page_table_depth_to_hw(unsigned int page_table_depth
)
308 enum dcn_hubbub_page_table_depth depth
= 0;
310 switch (page_table_depth
) {
312 depth
= DCN_PAGE_TABLE_DEPTH_1_LEVEL
;
315 depth
= DCN_PAGE_TABLE_DEPTH_2_LEVEL
;
318 depth
= DCN_PAGE_TABLE_DEPTH_3_LEVEL
;
321 depth
= DCN_PAGE_TABLE_DEPTH_4_LEVEL
;
331 static enum dcn_hubbub_page_table_block_size
page_table_block_size_to_hw(unsigned int page_table_block_size
)
333 enum dcn_hubbub_page_table_block_size block_size
= 0;
335 switch (page_table_block_size
) {
337 block_size
= DCN_PAGE_TABLE_BLOCK_SIZE_4KB
;
340 block_size
= DCN_PAGE_TABLE_BLOCK_SIZE_64KB
;
344 block_size
= page_table_block_size
;
351 void hubbub2_init_vm_ctx(struct hubbub
*hubbub
,
352 struct dcn_hubbub_virt_addr_config
*va_config
,
355 struct dcn20_hubbub
*hubbub1
= TO_DCN20_HUBBUB(hubbub
);
356 struct dcn_vmid_page_table_config virt_config
;
358 virt_config
.page_table_start_addr
= va_config
->page_table_start_addr
>> 12;
359 virt_config
.page_table_end_addr
= va_config
->page_table_end_addr
>> 12;
360 virt_config
.depth
= page_table_depth_to_hw(va_config
->page_table_depth
);
361 virt_config
.block_size
= page_table_block_size_to_hw(va_config
->page_table_block_size
);
362 virt_config
.page_table_base_addr
= va_config
->page_table_base_addr
;
364 dcn20_vmid_setup(&hubbub1
->vmid
[vmid
], &virt_config
);
367 int hubbub2_init_dchub_sys_ctx(struct hubbub
*hubbub
,
368 struct dcn_hubbub_phys_addr_config
*pa_config
)
370 struct dcn20_hubbub
*hubbub1
= TO_DCN20_HUBBUB(hubbub
);
371 struct dcn_vmid_page_table_config phys_config
;
373 REG_SET(DCN_VM_FB_LOCATION_BASE
, 0,
374 FB_BASE
, pa_config
->system_aperture
.fb_base
>> 24);
375 REG_SET(DCN_VM_FB_LOCATION_TOP
, 0,
376 FB_TOP
, pa_config
->system_aperture
.fb_top
>> 24);
377 REG_SET(DCN_VM_FB_OFFSET
, 0,
378 FB_OFFSET
, pa_config
->system_aperture
.fb_offset
>> 24);
379 REG_SET(DCN_VM_AGP_BOT
, 0,
380 AGP_BOT
, pa_config
->system_aperture
.agp_bot
>> 24);
381 REG_SET(DCN_VM_AGP_TOP
, 0,
382 AGP_TOP
, pa_config
->system_aperture
.agp_top
>> 24);
383 REG_SET(DCN_VM_AGP_BASE
, 0,
384 AGP_BASE
, pa_config
->system_aperture
.agp_base
>> 24);
386 REG_SET(DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_MSB
, 0,
387 DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_MSB
, (pa_config
->page_table_default_page_addr
>> 44) & 0xF);
388 REG_SET(DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_LSB
, 0,
389 DCN_VM_PROTECTION_FAULT_DEFAULT_ADDR_LSB
, (pa_config
->page_table_default_page_addr
>> 12) & 0xFFFFFFFF);
391 if (pa_config
->gart_config
.page_table_start_addr
!= pa_config
->gart_config
.page_table_end_addr
) {
392 phys_config
.page_table_start_addr
= pa_config
->gart_config
.page_table_start_addr
>> 12;
393 phys_config
.page_table_end_addr
= pa_config
->gart_config
.page_table_end_addr
>> 12;
394 phys_config
.page_table_base_addr
= pa_config
->gart_config
.page_table_base_addr
;
395 phys_config
.depth
= 0;
396 phys_config
.block_size
= 0;
397 // Init VMID 0 based on PA config
398 dcn20_vmid_setup(&hubbub1
->vmid
[0], &phys_config
);
404 void hubbub2_update_dchub(struct hubbub
*hubbub
,
405 struct dchub_init_data
*dh_data
)
407 struct dcn20_hubbub
*hubbub1
= TO_DCN20_HUBBUB(hubbub
);
409 if (REG(DCN_VM_FB_LOCATION_TOP
) == 0)
412 switch (dh_data
->fb_mode
) {
413 case FRAME_BUFFER_MODE_ZFB_ONLY
:
414 /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/
415 REG_UPDATE(DCN_VM_FB_LOCATION_TOP
,
418 REG_UPDATE(DCN_VM_FB_LOCATION_BASE
,
421 /*This field defines the 24 MSBs, bits [47:24] of the 48 bit AGP Base*/
422 REG_UPDATE(DCN_VM_AGP_BASE
,
423 AGP_BASE
, dh_data
->zfb_phys_addr_base
>> 24);
425 /*This field defines the bottom range of the AGP aperture and represents the 24*/
426 /*MSBs, bits [47:24] of the 48 address bits*/
427 REG_UPDATE(DCN_VM_AGP_BOT
,
428 AGP_BOT
, dh_data
->zfb_mc_base_addr
>> 24);
430 /*This field defines the top range of the AGP aperture and represents the 24*/
431 /*MSBs, bits [47:24] of the 48 address bits*/
432 REG_UPDATE(DCN_VM_AGP_TOP
,
433 AGP_TOP
, (dh_data
->zfb_mc_base_addr
+
434 dh_data
->zfb_size_in_byte
- 1) >> 24);
436 case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL
:
437 /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/
439 /*This field defines the 24 MSBs, bits [47:24] of the 48 bit AGP Base*/
440 REG_UPDATE(DCN_VM_AGP_BASE
,
441 AGP_BASE
, dh_data
->zfb_phys_addr_base
>> 24);
443 /*This field defines the bottom range of the AGP aperture and represents the 24*/
444 /*MSBs, bits [47:24] of the 48 address bits*/
445 REG_UPDATE(DCN_VM_AGP_BOT
,
446 AGP_BOT
, dh_data
->zfb_mc_base_addr
>> 24);
448 /*This field defines the top range of the AGP aperture and represents the 24*/
449 /*MSBs, bits [47:24] of the 48 address bits*/
450 REG_UPDATE(DCN_VM_AGP_TOP
,
451 AGP_TOP
, (dh_data
->zfb_mc_base_addr
+
452 dh_data
->zfb_size_in_byte
- 1) >> 24);
454 case FRAME_BUFFER_MODE_LOCAL_ONLY
:
455 /*Should not touch FB LOCATION (should be done by VBIOS)*/
457 /*This field defines the 24 MSBs, bits [47:24] of the 48 bit AGP Base*/
458 REG_UPDATE(DCN_VM_AGP_BASE
,
461 /*This field defines the bottom range of the AGP aperture and represents the 24*/
462 /*MSBs, bits [47:24] of the 48 address bits*/
463 REG_UPDATE(DCN_VM_AGP_BOT
,
466 /*This field defines the top range of the AGP aperture and represents the 24*/
467 /*MSBs, bits [47:24] of the 48 address bits*/
468 REG_UPDATE(DCN_VM_AGP_TOP
,
475 dh_data
->dchub_initialzied
= true;
476 dh_data
->dchub_info_valid
= false;
479 void hubbub2_wm_read_state(struct hubbub
*hubbub
,
480 struct dcn_hubbub_wm
*wm
)
482 struct dcn20_hubbub
*hubbub1
= TO_DCN20_HUBBUB(hubbub
);
484 struct dcn_hubbub_wm_set
*s
;
486 memset(wm
, 0, sizeof(struct dcn_hubbub_wm
));
490 s
->data_urgent
= REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A
);
491 if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A
))
492 s
->pte_meta_urgent
= REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A
);
493 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A
)) {
494 s
->sr_enter
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A
);
495 s
->sr_exit
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A
);
497 s
->dram_clk_chanage
= REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A
);
501 s
->data_urgent
= REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B
);
502 if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B
))
503 s
->pte_meta_urgent
= REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B
);
504 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B
)) {
505 s
->sr_enter
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B
);
506 s
->sr_exit
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B
);
508 s
->dram_clk_chanage
= REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B
);
512 s
->data_urgent
= REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C
);
513 if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C
))
514 s
->pte_meta_urgent
= REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C
);
515 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C
)) {
516 s
->sr_enter
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C
);
517 s
->sr_exit
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C
);
519 s
->dram_clk_chanage
= REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C
);
523 s
->data_urgent
= REG_READ(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D
);
524 if (REG(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D
))
525 s
->pte_meta_urgent
= REG_READ(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D
);
526 if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D
)) {
527 s
->sr_enter
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D
);
528 s
->sr_exit
= REG_READ(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D
);
530 s
->dram_clk_chanage
= REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D
);
533 void hubbub2_get_dchub_ref_freq(struct hubbub
*hubbub
,
534 unsigned int dccg_ref_freq_inKhz
,
535 unsigned int *dchub_ref_freq_inKhz
)
537 struct dcn20_hubbub
*hubbub1
= TO_DCN20_HUBBUB(hubbub
);
538 uint32_t ref_div
= 0;
541 REG_GET_2(DCHUBBUB_GLOBAL_TIMER_CNTL
, DCHUBBUB_GLOBAL_TIMER_REFDIV
, &ref_div
,
542 DCHUBBUB_GLOBAL_TIMER_ENABLE
, &ref_en
);
546 *dchub_ref_freq_inKhz
= dccg_ref_freq_inKhz
/ 2;
548 *dchub_ref_freq_inKhz
= dccg_ref_freq_inKhz
;
550 // DC hub reference frequency must be around 50Mhz, otherwise there may be
551 // overflow/underflow issues when doing HUBBUB programming
552 if (*dchub_ref_freq_inKhz
< 40000 || *dchub_ref_freq_inKhz
> 60000)
553 ASSERT_CRITICAL(false);
557 *dchub_ref_freq_inKhz
= dccg_ref_freq_inKhz
;
559 // HUBBUB global timer must be enabled.
560 ASSERT_CRITICAL(false);
565 static void hubbub2_program_watermarks(
566 struct hubbub
*hubbub
,
567 struct dcn_watermark_set
*watermarks
,
568 unsigned int refclk_mhz
,
571 struct dcn20_hubbub
*hubbub1
= TO_DCN20_HUBBUB(hubbub
);
573 * Need to clamp to max of the register values (i.e. no wrap)
574 * for dcn1, all wm registers are 21-bit wide
576 hubbub1_program_urgent_watermarks(hubbub
, watermarks
, refclk_mhz
, safe_to_lower
);
577 hubbub1_program_stutter_watermarks(hubbub
, watermarks
, refclk_mhz
, safe_to_lower
);
580 * There's a special case when going from p-state support to p-state unsupported
581 * here we are going to LOWER watermarks to go to dummy p-state only, but this has
582 * to be done prepare_bandwidth, not optimize
584 if (hubbub1
->base
.ctx
->dc
->clk_mgr
->clks
.prev_p_state_change_support
== true &&
585 hubbub1
->base
.ctx
->dc
->clk_mgr
->clks
.p_state_change_support
== false)
586 safe_to_lower
= true;
588 hubbub1_program_pstate_watermarks(hubbub
, watermarks
, refclk_mhz
, safe_to_lower
);
590 REG_SET(DCHUBBUB_ARB_SAT_LEVEL
, 0,
591 DCHUBBUB_ARB_SAT_LEVEL
, 60 * refclk_mhz
);
592 REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND
, DCHUBBUB_ARB_MIN_REQ_OUTSTAND
, 180);
594 hubbub
->funcs
->allow_self_refresh_control(hubbub
, !hubbub
->ctx
->dc
->debug
.disable_stutter
);
597 static const struct hubbub_funcs hubbub2_funcs
= {
598 .update_dchub
= hubbub2_update_dchub
,
599 .init_dchub_sys_ctx
= hubbub2_init_dchub_sys_ctx
,
600 .init_vm_ctx
= hubbub2_init_vm_ctx
,
601 .dcc_support_swizzle
= hubbub2_dcc_support_swizzle
,
602 .dcc_support_pixel_format
= hubbub2_dcc_support_pixel_format
,
603 .get_dcc_compression_cap
= hubbub2_get_dcc_compression_cap
,
604 .wm_read_state
= hubbub2_wm_read_state
,
605 .get_dchub_ref_freq
= hubbub2_get_dchub_ref_freq
,
606 .program_watermarks
= hubbub2_program_watermarks
,
607 .is_allow_self_refresh_enabled
= hubbub1_is_allow_self_refresh_enabled
,
608 .allow_self_refresh_control
= hubbub1_allow_self_refresh_control
,
611 void hubbub2_construct(struct dcn20_hubbub
*hubbub
,
612 struct dc_context
*ctx
,
613 const struct dcn_hubbub_registers
*hubbub_regs
,
614 const struct dcn_hubbub_shift
*hubbub_shift
,
615 const struct dcn_hubbub_mask
*hubbub_mask
)
617 hubbub
->base
.ctx
= ctx
;
619 hubbub
->base
.funcs
= &hubbub2_funcs
;
621 hubbub
->regs
= hubbub_regs
;
622 hubbub
->shifts
= hubbub_shift
;
623 hubbub
->masks
= hubbub_mask
;
625 hubbub
->debug_test_index_pstate
= 0xB;
626 hubbub
->detile_buf_size
= 164 * 1024; /* 164KB for DCN2.0 */