2 * Copyright 2012-15 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.
25 #include "dm_services.h"
26 #include "dce_calcs.h"
27 #include "reg_helper.h"
28 #include "basics/conversion.h"
29 #include "dcn10_hubp.h"
38 #define FN(reg_name, field_name) \
39 hubp1->hubp_shift->field_name, hubp1->hubp_mask->field_name
41 void hubp1_set_blank(struct hubp
*hubp
, bool blank
)
43 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
44 uint32_t blank_en
= blank
? 1 : 0;
46 REG_UPDATE_2(DCHUBP_CNTL
,
47 HUBP_BLANK_EN
, blank_en
,
48 HUBP_TTU_DISABLE
, blank_en
);
51 uint32_t reg_val
= REG_READ(DCHUBP_CNTL
);
54 /* init sequence workaround: in case HUBP is
55 * power gated, this wait would timeout.
57 * we just wrote reg_val to non-0, if it stay 0
58 * it means HUBP is gated
61 HUBP_NO_OUTSTANDING_REQ
, 1,
66 hubp
->opp_id
= OPP_ID_INVALID
;
70 static void hubp1_disconnect(struct hubp
*hubp
)
72 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
74 REG_UPDATE(DCHUBP_CNTL
,
77 REG_UPDATE(CURSOR_CONTROL
,
81 static void hubp1_disable_control(struct hubp
*hubp
, bool disable_hubp
)
83 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
84 uint32_t disable
= disable_hubp
? 1 : 0;
86 REG_UPDATE(DCHUBP_CNTL
,
87 HUBP_DISABLE
, disable
);
90 static unsigned int hubp1_get_underflow_status(struct hubp
*hubp
)
92 uint32_t hubp_underflow
= 0;
93 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
96 HUBP_UNDERFLOW_STATUS
,
99 return hubp_underflow
;
103 void hubp1_clear_underflow(struct hubp
*hubp
)
105 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
107 REG_UPDATE(DCHUBP_CNTL
, HUBP_UNDERFLOW_CLEAR
, 1);
110 static void hubp1_set_hubp_blank_en(struct hubp
*hubp
, bool blank
)
112 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
113 uint32_t blank_en
= blank
? 1 : 0;
115 REG_UPDATE(DCHUBP_CNTL
, HUBP_BLANK_EN
, blank_en
);
118 void hubp1_vready_workaround(struct hubp
*hubp
,
119 struct _vcs_dpi_display_pipe_dest_params_st
*pipe_dest
)
122 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
124 /* set HBUBREQ_DEBUG_DB[12] = 1 */
125 value
= REG_READ(HUBPREQ_DEBUG_DB
);
127 /* hack mode disable */
131 if ((pipe_dest
->vstartup_start
- 2*(pipe_dest
->vready_offset
+pipe_dest
->vupdate_width
132 + pipe_dest
->vupdate_offset
) / pipe_dest
->htotal
) <= pipe_dest
->vblank_end
) {
133 /* if (eco_fix_needed(otg_global_sync_timing)
134 * set HBUBREQ_DEBUG_DB[12] = 1 */
138 REG_WRITE(HUBPREQ_DEBUG_DB
, value
);
141 void hubp1_program_tiling(
143 const union dc_tiling_info
*info
,
144 const enum surface_pixel_format pixel_format
)
146 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
148 REG_UPDATE_6(DCSURF_ADDR_CONFIG
,
149 NUM_PIPES
, log_2(info
->gfx9
.num_pipes
),
150 NUM_BANKS
, log_2(info
->gfx9
.num_banks
),
151 PIPE_INTERLEAVE
, info
->gfx9
.pipe_interleave
,
152 NUM_SE
, log_2(info
->gfx9
.num_shader_engines
),
153 NUM_RB_PER_SE
, log_2(info
->gfx9
.num_rb_per_se
),
154 MAX_COMPRESSED_FRAGS
, log_2(info
->gfx9
.max_compressed_frags
));
156 REG_UPDATE_4(DCSURF_TILING_CONFIG
,
157 SW_MODE
, info
->gfx9
.swizzle
,
158 META_LINEAR
, info
->gfx9
.meta_linear
,
159 RB_ALIGNED
, info
->gfx9
.rb_aligned
,
160 PIPE_ALIGNED
, info
->gfx9
.pipe_aligned
);
163 void hubp1_program_size(
165 enum surface_pixel_format format
,
166 const struct plane_size
*plane_size
,
167 struct dc_plane_dcc_param
*dcc
)
169 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
170 uint32_t pitch
, meta_pitch
, pitch_c
, meta_pitch_c
;
172 /* Program data and meta surface pitch (calculation from addrlib)
175 if (format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
&& format
< SURFACE_PIXEL_FORMAT_SUBSAMPLE_END
) {
176 ASSERT(plane_size
->chroma_pitch
!= 0);
177 /* Chroma pitch zero can cause system hang! */
179 pitch
= plane_size
->surface_pitch
- 1;
180 meta_pitch
= dcc
->meta_pitch
- 1;
181 pitch_c
= plane_size
->chroma_pitch
- 1;
182 meta_pitch_c
= dcc
->meta_pitch_c
- 1;
184 pitch
= plane_size
->surface_pitch
- 1;
185 meta_pitch
= dcc
->meta_pitch
- 1;
195 REG_UPDATE_2(DCSURF_SURFACE_PITCH
,
196 PITCH
, pitch
, META_PITCH
, meta_pitch
);
198 if (format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
)
199 REG_UPDATE_2(DCSURF_SURFACE_PITCH_C
,
200 PITCH_C
, pitch_c
, META_PITCH_C
, meta_pitch_c
);
203 void hubp1_program_rotation(
205 enum dc_rotation_angle rotation
,
206 bool horizontal_mirror
)
208 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
212 if (horizontal_mirror
)
217 /* Program rotation angle and horz mirror - no mirror */
218 if (rotation
== ROTATION_ANGLE_0
)
219 REG_UPDATE_2(DCSURF_SURFACE_CONFIG
,
221 H_MIRROR_EN
, mirror
);
222 else if (rotation
== ROTATION_ANGLE_90
)
223 REG_UPDATE_2(DCSURF_SURFACE_CONFIG
,
225 H_MIRROR_EN
, mirror
);
226 else if (rotation
== ROTATION_ANGLE_180
)
227 REG_UPDATE_2(DCSURF_SURFACE_CONFIG
,
229 H_MIRROR_EN
, mirror
);
230 else if (rotation
== ROTATION_ANGLE_270
)
231 REG_UPDATE_2(DCSURF_SURFACE_CONFIG
,
233 H_MIRROR_EN
, mirror
);
236 void hubp1_program_pixel_format(
238 enum surface_pixel_format format
)
240 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
241 uint32_t red_bar
= 3;
242 uint32_t blue_bar
= 2;
244 /* swap for ABGR format */
245 if (format
== SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
246 || format
== SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
247 || format
== SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
248 || format
== SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
) {
253 REG_UPDATE_2(HUBPRET_CONTROL
,
254 CROSSBAR_SRC_CB_B
, blue_bar
,
255 CROSSBAR_SRC_CR_R
, red_bar
);
257 /* Mapping is same as ipp programming (cnvc) */
260 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555
:
261 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
262 SURFACE_PIXEL_FORMAT
, 1);
264 case SURFACE_PIXEL_FORMAT_GRPH_RGB565
:
265 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
266 SURFACE_PIXEL_FORMAT
, 3);
268 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888
:
269 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
:
270 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
271 SURFACE_PIXEL_FORMAT
, 8);
273 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010
:
274 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
:
275 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
:
276 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
277 SURFACE_PIXEL_FORMAT
, 10);
279 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616
:
280 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
281 SURFACE_PIXEL_FORMAT
, 22);
283 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F
:
284 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
:/*we use crossbar already*/
285 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
286 SURFACE_PIXEL_FORMAT
, 24);
289 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr
:
290 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
291 SURFACE_PIXEL_FORMAT
, 65);
293 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb
:
294 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
295 SURFACE_PIXEL_FORMAT
, 64);
297 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr
:
298 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
299 SURFACE_PIXEL_FORMAT
, 67);
301 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb
:
302 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
303 SURFACE_PIXEL_FORMAT
, 66);
305 case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888
:
306 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
307 SURFACE_PIXEL_FORMAT
, 12);
309 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX
:
310 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
311 SURFACE_PIXEL_FORMAT
, 112);
313 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX
:
314 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
315 SURFACE_PIXEL_FORMAT
, 113);
317 case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010
:
318 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
319 SURFACE_PIXEL_FORMAT
, 114);
321 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT
:
322 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
323 SURFACE_PIXEL_FORMAT
, 118);
325 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT
:
326 REG_UPDATE(DCSURF_SURFACE_CONFIG
,
327 SURFACE_PIXEL_FORMAT
, 119);
334 /* don't see the need of program the xbar in DCN 1.0 */
337 bool hubp1_program_surface_flip_and_addr(
339 const struct dc_plane_address
*address
,
342 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
346 REG_UPDATE(DCSURF_FLIP_CONTROL
,
347 SURFACE_FLIP_TYPE
, flip_immediate
);
350 if (address
->type
== PLN_ADDR_TYPE_GRPH_STEREO
) {
351 REG_UPDATE(DCSURF_FLIP_CONTROL
, SURFACE_FLIP_MODE_FOR_STEREOSYNC
, 0x1);
352 REG_UPDATE(DCSURF_FLIP_CONTROL
, SURFACE_FLIP_IN_STEREOSYNC
, 0x1);
355 // turn off stereo if not in stereo
356 REG_UPDATE(DCSURF_FLIP_CONTROL
, SURFACE_FLIP_MODE_FOR_STEREOSYNC
, 0x0);
357 REG_UPDATE(DCSURF_FLIP_CONTROL
, SURFACE_FLIP_IN_STEREOSYNC
, 0x0);
362 /* HW automatically latch rest of address register on write to
363 * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used
365 * program high first and then the low addr, order matters!
367 switch (address
->type
) {
368 case PLN_ADDR_TYPE_GRAPHICS
:
369 /* DCN1.0 does not support const color
370 * TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1
371 * base on address->grph.dcc_const_color
372 * x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma
373 * x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma
376 if (address
->grph
.addr
.quad_part
== 0)
379 REG_UPDATE_2(DCSURF_SURFACE_CONTROL
,
380 PRIMARY_SURFACE_TMZ
, address
->tmz_surface
,
381 PRIMARY_META_SURFACE_TMZ
, address
->tmz_surface
);
383 if (address
->grph
.meta_addr
.quad_part
!= 0) {
384 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH
, 0,
385 PRIMARY_META_SURFACE_ADDRESS_HIGH
,
386 address
->grph
.meta_addr
.high_part
);
388 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS
, 0,
389 PRIMARY_META_SURFACE_ADDRESS
,
390 address
->grph
.meta_addr
.low_part
);
393 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH
, 0,
394 PRIMARY_SURFACE_ADDRESS_HIGH
,
395 address
->grph
.addr
.high_part
);
397 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS
, 0,
398 PRIMARY_SURFACE_ADDRESS
,
399 address
->grph
.addr
.low_part
);
401 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE
:
402 if (address
->video_progressive
.luma_addr
.quad_part
== 0
403 || address
->video_progressive
.chroma_addr
.quad_part
== 0)
406 REG_UPDATE_4(DCSURF_SURFACE_CONTROL
,
407 PRIMARY_SURFACE_TMZ
, address
->tmz_surface
,
408 PRIMARY_SURFACE_TMZ_C
, address
->tmz_surface
,
409 PRIMARY_META_SURFACE_TMZ
, address
->tmz_surface
,
410 PRIMARY_META_SURFACE_TMZ_C
, address
->tmz_surface
);
412 if (address
->video_progressive
.luma_meta_addr
.quad_part
!= 0) {
413 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C
, 0,
414 PRIMARY_META_SURFACE_ADDRESS_HIGH_C
,
415 address
->video_progressive
.chroma_meta_addr
.high_part
);
417 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C
, 0,
418 PRIMARY_META_SURFACE_ADDRESS_C
,
419 address
->video_progressive
.chroma_meta_addr
.low_part
);
421 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH
, 0,
422 PRIMARY_META_SURFACE_ADDRESS_HIGH
,
423 address
->video_progressive
.luma_meta_addr
.high_part
);
425 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS
, 0,
426 PRIMARY_META_SURFACE_ADDRESS
,
427 address
->video_progressive
.luma_meta_addr
.low_part
);
430 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C
, 0,
431 PRIMARY_SURFACE_ADDRESS_HIGH_C
,
432 address
->video_progressive
.chroma_addr
.high_part
);
434 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C
, 0,
435 PRIMARY_SURFACE_ADDRESS_C
,
436 address
->video_progressive
.chroma_addr
.low_part
);
438 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH
, 0,
439 PRIMARY_SURFACE_ADDRESS_HIGH
,
440 address
->video_progressive
.luma_addr
.high_part
);
442 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS
, 0,
443 PRIMARY_SURFACE_ADDRESS
,
444 address
->video_progressive
.luma_addr
.low_part
);
446 case PLN_ADDR_TYPE_GRPH_STEREO
:
447 if (address
->grph_stereo
.left_addr
.quad_part
== 0)
449 if (address
->grph_stereo
.right_addr
.quad_part
== 0)
452 REG_UPDATE_8(DCSURF_SURFACE_CONTROL
,
453 PRIMARY_SURFACE_TMZ
, address
->tmz_surface
,
454 PRIMARY_SURFACE_TMZ_C
, address
->tmz_surface
,
455 PRIMARY_META_SURFACE_TMZ
, address
->tmz_surface
,
456 PRIMARY_META_SURFACE_TMZ_C
, address
->tmz_surface
,
457 SECONDARY_SURFACE_TMZ
, address
->tmz_surface
,
458 SECONDARY_SURFACE_TMZ_C
, address
->tmz_surface
,
459 SECONDARY_META_SURFACE_TMZ
, address
->tmz_surface
,
460 SECONDARY_META_SURFACE_TMZ_C
, address
->tmz_surface
);
462 if (address
->grph_stereo
.right_meta_addr
.quad_part
!= 0) {
464 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH
, 0,
465 SECONDARY_META_SURFACE_ADDRESS_HIGH
,
466 address
->grph_stereo
.right_meta_addr
.high_part
);
468 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS
, 0,
469 SECONDARY_META_SURFACE_ADDRESS
,
470 address
->grph_stereo
.right_meta_addr
.low_part
);
472 if (address
->grph_stereo
.left_meta_addr
.quad_part
!= 0) {
474 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH
, 0,
475 PRIMARY_META_SURFACE_ADDRESS_HIGH
,
476 address
->grph_stereo
.left_meta_addr
.high_part
);
478 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS
, 0,
479 PRIMARY_META_SURFACE_ADDRESS
,
480 address
->grph_stereo
.left_meta_addr
.low_part
);
483 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH
, 0,
484 SECONDARY_SURFACE_ADDRESS_HIGH
,
485 address
->grph_stereo
.right_addr
.high_part
);
487 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS
, 0,
488 SECONDARY_SURFACE_ADDRESS
,
489 address
->grph_stereo
.right_addr
.low_part
);
491 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH
, 0,
492 PRIMARY_SURFACE_ADDRESS_HIGH
,
493 address
->grph_stereo
.left_addr
.high_part
);
495 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS
, 0,
496 PRIMARY_SURFACE_ADDRESS
,
497 address
->grph_stereo
.left_addr
.low_part
);
504 hubp
->request_address
= *address
;
509 void hubp1_dcc_control(struct hubp
*hubp
, bool enable
,
510 enum hubp_ind_block_size independent_64b_blks
)
512 uint32_t dcc_en
= enable
? 1 : 0;
513 uint32_t dcc_ind_64b_blk
= independent_64b_blks
? 1 : 0;
514 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
516 REG_UPDATE_4(DCSURF_SURFACE_CONTROL
,
517 PRIMARY_SURFACE_DCC_EN
, dcc_en
,
518 PRIMARY_SURFACE_DCC_IND_64B_BLK
, dcc_ind_64b_blk
,
519 SECONDARY_SURFACE_DCC_EN
, dcc_en
,
520 SECONDARY_SURFACE_DCC_IND_64B_BLK
, dcc_ind_64b_blk
);
523 void hubp1_program_surface_config(
525 enum surface_pixel_format format
,
526 union dc_tiling_info
*tiling_info
,
527 struct plane_size
*plane_size
,
528 enum dc_rotation_angle rotation
,
529 struct dc_plane_dcc_param
*dcc
,
530 bool horizontal_mirror
,
531 unsigned int compat_level
)
533 hubp1_dcc_control(hubp
, dcc
->enable
, dcc
->independent_64b_blks
);
534 hubp1_program_tiling(hubp
, tiling_info
, format
);
535 hubp1_program_size(hubp
, format
, plane_size
, dcc
);
536 hubp1_program_rotation(hubp
, rotation
, horizontal_mirror
);
537 hubp1_program_pixel_format(hubp
, format
);
540 void hubp1_program_requestor(
542 struct _vcs_dpi_display_rq_regs_st
*rq_regs
)
544 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
546 REG_UPDATE(HUBPRET_CONTROL
,
547 DET_BUF_PLANE1_BASE_ADDRESS
, rq_regs
->plane1_base_address
);
548 REG_SET_4(DCN_EXPANSION_MODE
, 0,
549 DRQ_EXPANSION_MODE
, rq_regs
->drq_expansion_mode
,
550 PRQ_EXPANSION_MODE
, rq_regs
->prq_expansion_mode
,
551 MRQ_EXPANSION_MODE
, rq_regs
->mrq_expansion_mode
,
552 CRQ_EXPANSION_MODE
, rq_regs
->crq_expansion_mode
);
553 REG_SET_8(DCHUBP_REQ_SIZE_CONFIG
, 0,
554 CHUNK_SIZE
, rq_regs
->rq_regs_l
.chunk_size
,
555 MIN_CHUNK_SIZE
, rq_regs
->rq_regs_l
.min_chunk_size
,
556 META_CHUNK_SIZE
, rq_regs
->rq_regs_l
.meta_chunk_size
,
557 MIN_META_CHUNK_SIZE
, rq_regs
->rq_regs_l
.min_meta_chunk_size
,
558 DPTE_GROUP_SIZE
, rq_regs
->rq_regs_l
.dpte_group_size
,
559 MPTE_GROUP_SIZE
, rq_regs
->rq_regs_l
.mpte_group_size
,
560 SWATH_HEIGHT
, rq_regs
->rq_regs_l
.swath_height
,
561 PTE_ROW_HEIGHT_LINEAR
, rq_regs
->rq_regs_l
.pte_row_height_linear
);
562 REG_SET_8(DCHUBP_REQ_SIZE_CONFIG_C
, 0,
563 CHUNK_SIZE_C
, rq_regs
->rq_regs_c
.chunk_size
,
564 MIN_CHUNK_SIZE_C
, rq_regs
->rq_regs_c
.min_chunk_size
,
565 META_CHUNK_SIZE_C
, rq_regs
->rq_regs_c
.meta_chunk_size
,
566 MIN_META_CHUNK_SIZE_C
, rq_regs
->rq_regs_c
.min_meta_chunk_size
,
567 DPTE_GROUP_SIZE_C
, rq_regs
->rq_regs_c
.dpte_group_size
,
568 MPTE_GROUP_SIZE_C
, rq_regs
->rq_regs_c
.mpte_group_size
,
569 SWATH_HEIGHT_C
, rq_regs
->rq_regs_c
.swath_height
,
570 PTE_ROW_HEIGHT_LINEAR_C
, rq_regs
->rq_regs_c
.pte_row_height_linear
);
574 void hubp1_program_deadline(
576 struct _vcs_dpi_display_dlg_regs_st
*dlg_attr
,
577 struct _vcs_dpi_display_ttu_regs_st
*ttu_attr
)
579 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
582 REG_SET_2(BLANK_OFFSET_0
, 0,
583 REFCYC_H_BLANK_END
, dlg_attr
->refcyc_h_blank_end
,
584 DLG_V_BLANK_END
, dlg_attr
->dlg_vblank_end
);
586 REG_SET(BLANK_OFFSET_1
, 0,
587 MIN_DST_Y_NEXT_START
, dlg_attr
->min_dst_y_next_start
);
589 REG_SET(DST_DIMENSIONS
, 0,
590 REFCYC_PER_HTOTAL
, dlg_attr
->refcyc_per_htotal
);
592 REG_SET_2(DST_AFTER_SCALER
, 0,
593 REFCYC_X_AFTER_SCALER
, dlg_attr
->refcyc_x_after_scaler
,
594 DST_Y_AFTER_SCALER
, dlg_attr
->dst_y_after_scaler
);
596 REG_SET(REF_FREQ_TO_PIX_FREQ
, 0,
597 REF_FREQ_TO_PIX_FREQ
, dlg_attr
->ref_freq_to_pix_freq
);
599 /* DLG - Per luma/chroma */
600 REG_SET(VBLANK_PARAMETERS_1
, 0,
601 REFCYC_PER_PTE_GROUP_VBLANK_L
, dlg_attr
->refcyc_per_pte_group_vblank_l
);
603 if (REG(NOM_PARAMETERS_0
))
604 REG_SET(NOM_PARAMETERS_0
, 0,
605 DST_Y_PER_PTE_ROW_NOM_L
, dlg_attr
->dst_y_per_pte_row_nom_l
);
607 if (REG(NOM_PARAMETERS_1
))
608 REG_SET(NOM_PARAMETERS_1
, 0,
609 REFCYC_PER_PTE_GROUP_NOM_L
, dlg_attr
->refcyc_per_pte_group_nom_l
);
611 REG_SET(NOM_PARAMETERS_4
, 0,
612 DST_Y_PER_META_ROW_NOM_L
, dlg_attr
->dst_y_per_meta_row_nom_l
);
614 REG_SET(NOM_PARAMETERS_5
, 0,
615 REFCYC_PER_META_CHUNK_NOM_L
, dlg_attr
->refcyc_per_meta_chunk_nom_l
);
617 REG_SET_2(PER_LINE_DELIVERY
, 0,
618 REFCYC_PER_LINE_DELIVERY_L
, dlg_attr
->refcyc_per_line_delivery_l
,
619 REFCYC_PER_LINE_DELIVERY_C
, dlg_attr
->refcyc_per_line_delivery_c
);
621 REG_SET(VBLANK_PARAMETERS_2
, 0,
622 REFCYC_PER_PTE_GROUP_VBLANK_C
, dlg_attr
->refcyc_per_pte_group_vblank_c
);
624 if (REG(NOM_PARAMETERS_2
))
625 REG_SET(NOM_PARAMETERS_2
, 0,
626 DST_Y_PER_PTE_ROW_NOM_C
, dlg_attr
->dst_y_per_pte_row_nom_c
);
628 if (REG(NOM_PARAMETERS_3
))
629 REG_SET(NOM_PARAMETERS_3
, 0,
630 REFCYC_PER_PTE_GROUP_NOM_C
, dlg_attr
->refcyc_per_pte_group_nom_c
);
632 REG_SET(NOM_PARAMETERS_6
, 0,
633 DST_Y_PER_META_ROW_NOM_C
, dlg_attr
->dst_y_per_meta_row_nom_c
);
635 REG_SET(NOM_PARAMETERS_7
, 0,
636 REFCYC_PER_META_CHUNK_NOM_C
, dlg_attr
->refcyc_per_meta_chunk_nom_c
);
639 REG_SET_2(DCN_TTU_QOS_WM
, 0,
640 QoS_LEVEL_LOW_WM
, ttu_attr
->qos_level_low_wm
,
641 QoS_LEVEL_HIGH_WM
, ttu_attr
->qos_level_high_wm
);
643 /* TTU - per luma/chroma */
644 /* Assumed surf0 is luma and 1 is chroma */
646 REG_SET_3(DCN_SURF0_TTU_CNTL0
, 0,
647 REFCYC_PER_REQ_DELIVERY
, ttu_attr
->refcyc_per_req_delivery_l
,
648 QoS_LEVEL_FIXED
, ttu_attr
->qos_level_fixed_l
,
649 QoS_RAMP_DISABLE
, ttu_attr
->qos_ramp_disable_l
);
651 REG_SET_3(DCN_SURF1_TTU_CNTL0
, 0,
652 REFCYC_PER_REQ_DELIVERY
, ttu_attr
->refcyc_per_req_delivery_c
,
653 QoS_LEVEL_FIXED
, ttu_attr
->qos_level_fixed_c
,
654 QoS_RAMP_DISABLE
, ttu_attr
->qos_ramp_disable_c
);
656 REG_SET_3(DCN_CUR0_TTU_CNTL0
, 0,
657 REFCYC_PER_REQ_DELIVERY
, ttu_attr
->refcyc_per_req_delivery_cur0
,
658 QoS_LEVEL_FIXED
, ttu_attr
->qos_level_fixed_cur0
,
659 QoS_RAMP_DISABLE
, ttu_attr
->qos_ramp_disable_cur0
);
662 static void hubp1_setup(
664 struct _vcs_dpi_display_dlg_regs_st
*dlg_attr
,
665 struct _vcs_dpi_display_ttu_regs_st
*ttu_attr
,
666 struct _vcs_dpi_display_rq_regs_st
*rq_regs
,
667 struct _vcs_dpi_display_pipe_dest_params_st
*pipe_dest
)
669 /* otg is locked when this func is called. Register are double buffered.
670 * disable the requestors is not needed
672 hubp1_program_requestor(hubp
, rq_regs
);
673 hubp1_program_deadline(hubp
, dlg_attr
, ttu_attr
);
674 hubp1_vready_workaround(hubp
, pipe_dest
);
677 static void hubp1_setup_interdependent(
679 struct _vcs_dpi_display_dlg_regs_st
*dlg_attr
,
680 struct _vcs_dpi_display_ttu_regs_st
*ttu_attr
)
682 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
684 REG_SET_2(PREFETCH_SETTINS
, 0,
685 DST_Y_PREFETCH
, dlg_attr
->dst_y_prefetch
,
686 VRATIO_PREFETCH
, dlg_attr
->vratio_prefetch
);
688 REG_SET(PREFETCH_SETTINS_C
, 0,
689 VRATIO_PREFETCH_C
, dlg_attr
->vratio_prefetch_c
);
691 REG_SET_2(VBLANK_PARAMETERS_0
, 0,
692 DST_Y_PER_VM_VBLANK
, dlg_attr
->dst_y_per_vm_vblank
,
693 DST_Y_PER_ROW_VBLANK
, dlg_attr
->dst_y_per_row_vblank
);
695 REG_SET(VBLANK_PARAMETERS_3
, 0,
696 REFCYC_PER_META_CHUNK_VBLANK_L
, dlg_attr
->refcyc_per_meta_chunk_vblank_l
);
698 REG_SET(VBLANK_PARAMETERS_4
, 0,
699 REFCYC_PER_META_CHUNK_VBLANK_C
, dlg_attr
->refcyc_per_meta_chunk_vblank_c
);
701 REG_SET_2(PER_LINE_DELIVERY_PRE
, 0,
702 REFCYC_PER_LINE_DELIVERY_PRE_L
, dlg_attr
->refcyc_per_line_delivery_pre_l
,
703 REFCYC_PER_LINE_DELIVERY_PRE_C
, dlg_attr
->refcyc_per_line_delivery_pre_c
);
705 REG_SET(DCN_SURF0_TTU_CNTL1
, 0,
706 REFCYC_PER_REQ_DELIVERY_PRE
,
707 ttu_attr
->refcyc_per_req_delivery_pre_l
);
708 REG_SET(DCN_SURF1_TTU_CNTL1
, 0,
709 REFCYC_PER_REQ_DELIVERY_PRE
,
710 ttu_attr
->refcyc_per_req_delivery_pre_c
);
711 REG_SET(DCN_CUR0_TTU_CNTL1
, 0,
712 REFCYC_PER_REQ_DELIVERY_PRE
, ttu_attr
->refcyc_per_req_delivery_pre_cur0
);
714 REG_SET_2(DCN_GLOBAL_TTU_CNTL
, 0,
715 MIN_TTU_VBLANK
, ttu_attr
->min_ttu_vblank
,
716 QoS_LEVEL_FLIP
, ttu_attr
->qos_level_flip
);
719 bool hubp1_is_flip_pending(struct hubp
*hubp
)
721 uint32_t flip_pending
= 0;
722 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
723 struct dc_plane_address earliest_inuse_address
;
725 REG_GET(DCSURF_FLIP_CONTROL
,
726 SURFACE_FLIP_PENDING
, &flip_pending
);
728 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE
,
729 SURFACE_EARLIEST_INUSE_ADDRESS
, &earliest_inuse_address
.grph
.addr
.low_part
);
731 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH
,
732 SURFACE_EARLIEST_INUSE_ADDRESS_HIGH
, &earliest_inuse_address
.grph
.addr
.high_part
);
737 if (earliest_inuse_address
.grph
.addr
.quad_part
!= hubp
->request_address
.grph
.addr
.quad_part
)
743 uint32_t aperture_default_system
= 1;
744 uint32_t context0_default_system
; /* = 0;*/
746 static void hubp1_set_vm_system_aperture_settings(struct hubp
*hubp
,
747 struct vm_system_aperture_param
*apt
)
749 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
750 PHYSICAL_ADDRESS_LOC mc_vm_apt_default
;
751 PHYSICAL_ADDRESS_LOC mc_vm_apt_low
;
752 PHYSICAL_ADDRESS_LOC mc_vm_apt_high
;
754 mc_vm_apt_default
.quad_part
= apt
->sys_default
.quad_part
>> 12;
755 mc_vm_apt_low
.quad_part
= apt
->sys_low
.quad_part
>> 12;
756 mc_vm_apt_high
.quad_part
= apt
->sys_high
.quad_part
>> 12;
758 REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB
, 0,
759 MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM
, aperture_default_system
, /* 1 = system physical memory */
760 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB
, mc_vm_apt_default
.high_part
);
761 REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB
, 0,
762 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB
, mc_vm_apt_default
.low_part
);
764 REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB
, 0,
765 MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB
, mc_vm_apt_low
.high_part
);
766 REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB
, 0,
767 MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB
, mc_vm_apt_low
.low_part
);
769 REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB
, 0,
770 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB
, mc_vm_apt_high
.high_part
);
771 REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB
, 0,
772 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB
, mc_vm_apt_high
.low_part
);
775 static void hubp1_set_vm_context0_settings(struct hubp
*hubp
,
776 const struct vm_context0_param
*vm0
)
778 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
780 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB
, 0,
781 VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB
, vm0
->pte_base
.high_part
);
782 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB
, 0,
783 VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB
, vm0
->pte_base
.low_part
);
786 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB
, 0,
787 VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB
, vm0
->pte_start
.high_part
);
788 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB
, 0,
789 VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB
, vm0
->pte_start
.low_part
);
792 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB
, 0,
793 VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB
, vm0
->pte_end
.high_part
);
794 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB
, 0,
795 VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB
, vm0
->pte_end
.low_part
);
798 REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB
, 0,
799 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB
, vm0
->fault_default
.high_part
,
800 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM
, context0_default_system
);
801 REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB
, 0,
802 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB
, vm0
->fault_default
.low_part
);
804 /* control: enable VM PTE*/
805 REG_SET_2(DCN_VM_MX_L1_TLB_CNTL
, 0,
807 SYSTEM_ACCESS_MODE
, 3);
810 void min_set_viewport(
812 const struct rect
*viewport
,
813 const struct rect
*viewport_c
)
815 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
817 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION
, 0,
818 PRI_VIEWPORT_WIDTH
, viewport
->width
,
819 PRI_VIEWPORT_HEIGHT
, viewport
->height
);
821 REG_SET_2(DCSURF_PRI_VIEWPORT_START
, 0,
822 PRI_VIEWPORT_X_START
, viewport
->x
,
823 PRI_VIEWPORT_Y_START
, viewport
->y
);
826 REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION
, 0,
827 SEC_VIEWPORT_WIDTH
, viewport
->width
,
828 SEC_VIEWPORT_HEIGHT
, viewport
->height
);
830 REG_SET_2(DCSURF_SEC_VIEWPORT_START
, 0,
831 SEC_VIEWPORT_X_START
, viewport
->x
,
832 SEC_VIEWPORT_Y_START
, viewport
->y
);
834 /* DC supports NV12 only at the moment */
835 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C
, 0,
836 PRI_VIEWPORT_WIDTH_C
, viewport_c
->width
,
837 PRI_VIEWPORT_HEIGHT_C
, viewport_c
->height
);
839 REG_SET_2(DCSURF_PRI_VIEWPORT_START_C
, 0,
840 PRI_VIEWPORT_X_START_C
, viewport_c
->x
,
841 PRI_VIEWPORT_Y_START_C
, viewport_c
->y
);
843 REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION_C
, 0,
844 SEC_VIEWPORT_WIDTH_C
, viewport_c
->width
,
845 SEC_VIEWPORT_HEIGHT_C
, viewport_c
->height
);
847 REG_SET_2(DCSURF_SEC_VIEWPORT_START_C
, 0,
848 SEC_VIEWPORT_X_START_C
, viewport_c
->x
,
849 SEC_VIEWPORT_Y_START_C
, viewport_c
->y
);
852 void hubp1_read_state_common(struct hubp
*hubp
)
854 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
855 struct dcn_hubp_state
*s
= &hubp1
->state
;
856 struct _vcs_dpi_display_dlg_regs_st
*dlg_attr
= &s
->dlg_attr
;
857 struct _vcs_dpi_display_ttu_regs_st
*ttu_attr
= &s
->ttu_attr
;
858 struct _vcs_dpi_display_rq_regs_st
*rq_regs
= &s
->rq_regs
;
861 REG_GET(HUBPRET_CONTROL
,
862 DET_BUF_PLANE1_BASE_ADDRESS
, &rq_regs
->plane1_base_address
);
863 REG_GET_4(DCN_EXPANSION_MODE
,
864 DRQ_EXPANSION_MODE
, &rq_regs
->drq_expansion_mode
,
865 PRQ_EXPANSION_MODE
, &rq_regs
->prq_expansion_mode
,
866 MRQ_EXPANSION_MODE
, &rq_regs
->mrq_expansion_mode
,
867 CRQ_EXPANSION_MODE
, &rq_regs
->crq_expansion_mode
);
870 REG_GET_2(BLANK_OFFSET_0
,
871 REFCYC_H_BLANK_END
, &dlg_attr
->refcyc_h_blank_end
,
872 DLG_V_BLANK_END
, &dlg_attr
->dlg_vblank_end
);
874 REG_GET(BLANK_OFFSET_1
,
875 MIN_DST_Y_NEXT_START
, &dlg_attr
->min_dst_y_next_start
);
877 REG_GET(DST_DIMENSIONS
,
878 REFCYC_PER_HTOTAL
, &dlg_attr
->refcyc_per_htotal
);
880 REG_GET_2(DST_AFTER_SCALER
,
881 REFCYC_X_AFTER_SCALER
, &dlg_attr
->refcyc_x_after_scaler
,
882 DST_Y_AFTER_SCALER
, &dlg_attr
->dst_y_after_scaler
);
884 if (REG(PREFETCH_SETTINS
))
885 REG_GET_2(PREFETCH_SETTINS
,
886 DST_Y_PREFETCH
, &dlg_attr
->dst_y_prefetch
,
887 VRATIO_PREFETCH
, &dlg_attr
->vratio_prefetch
);
889 REG_GET_2(PREFETCH_SETTINGS
,
890 DST_Y_PREFETCH
, &dlg_attr
->dst_y_prefetch
,
891 VRATIO_PREFETCH
, &dlg_attr
->vratio_prefetch
);
893 REG_GET_2(VBLANK_PARAMETERS_0
,
894 DST_Y_PER_VM_VBLANK
, &dlg_attr
->dst_y_per_vm_vblank
,
895 DST_Y_PER_ROW_VBLANK
, &dlg_attr
->dst_y_per_row_vblank
);
897 REG_GET(REF_FREQ_TO_PIX_FREQ
,
898 REF_FREQ_TO_PIX_FREQ
, &dlg_attr
->ref_freq_to_pix_freq
);
900 /* DLG - Per luma/chroma */
901 REG_GET(VBLANK_PARAMETERS_1
,
902 REFCYC_PER_PTE_GROUP_VBLANK_L
, &dlg_attr
->refcyc_per_pte_group_vblank_l
);
904 REG_GET(VBLANK_PARAMETERS_3
,
905 REFCYC_PER_META_CHUNK_VBLANK_L
, &dlg_attr
->refcyc_per_meta_chunk_vblank_l
);
907 if (REG(NOM_PARAMETERS_0
))
908 REG_GET(NOM_PARAMETERS_0
,
909 DST_Y_PER_PTE_ROW_NOM_L
, &dlg_attr
->dst_y_per_pte_row_nom_l
);
911 if (REG(NOM_PARAMETERS_1
))
912 REG_GET(NOM_PARAMETERS_1
,
913 REFCYC_PER_PTE_GROUP_NOM_L
, &dlg_attr
->refcyc_per_pte_group_nom_l
);
915 REG_GET(NOM_PARAMETERS_4
,
916 DST_Y_PER_META_ROW_NOM_L
, &dlg_attr
->dst_y_per_meta_row_nom_l
);
918 REG_GET(NOM_PARAMETERS_5
,
919 REFCYC_PER_META_CHUNK_NOM_L
, &dlg_attr
->refcyc_per_meta_chunk_nom_l
);
921 REG_GET_2(PER_LINE_DELIVERY_PRE
,
922 REFCYC_PER_LINE_DELIVERY_PRE_L
, &dlg_attr
->refcyc_per_line_delivery_pre_l
,
923 REFCYC_PER_LINE_DELIVERY_PRE_C
, &dlg_attr
->refcyc_per_line_delivery_pre_c
);
925 REG_GET_2(PER_LINE_DELIVERY
,
926 REFCYC_PER_LINE_DELIVERY_L
, &dlg_attr
->refcyc_per_line_delivery_l
,
927 REFCYC_PER_LINE_DELIVERY_C
, &dlg_attr
->refcyc_per_line_delivery_c
);
929 if (REG(PREFETCH_SETTINS_C
))
930 REG_GET(PREFETCH_SETTINS_C
,
931 VRATIO_PREFETCH_C
, &dlg_attr
->vratio_prefetch_c
);
933 REG_GET(PREFETCH_SETTINGS_C
,
934 VRATIO_PREFETCH_C
, &dlg_attr
->vratio_prefetch_c
);
936 REG_GET(VBLANK_PARAMETERS_2
,
937 REFCYC_PER_PTE_GROUP_VBLANK_C
, &dlg_attr
->refcyc_per_pte_group_vblank_c
);
939 REG_GET(VBLANK_PARAMETERS_4
,
940 REFCYC_PER_META_CHUNK_VBLANK_C
, &dlg_attr
->refcyc_per_meta_chunk_vblank_c
);
942 if (REG(NOM_PARAMETERS_2
))
943 REG_GET(NOM_PARAMETERS_2
,
944 DST_Y_PER_PTE_ROW_NOM_C
, &dlg_attr
->dst_y_per_pte_row_nom_c
);
946 if (REG(NOM_PARAMETERS_3
))
947 REG_GET(NOM_PARAMETERS_3
,
948 REFCYC_PER_PTE_GROUP_NOM_C
, &dlg_attr
->refcyc_per_pte_group_nom_c
);
950 REG_GET(NOM_PARAMETERS_6
,
951 DST_Y_PER_META_ROW_NOM_C
, &dlg_attr
->dst_y_per_meta_row_nom_c
);
953 REG_GET(NOM_PARAMETERS_7
,
954 REFCYC_PER_META_CHUNK_NOM_C
, &dlg_attr
->refcyc_per_meta_chunk_nom_c
);
957 REG_GET_2(DCN_TTU_QOS_WM
,
958 QoS_LEVEL_LOW_WM
, &ttu_attr
->qos_level_low_wm
,
959 QoS_LEVEL_HIGH_WM
, &ttu_attr
->qos_level_high_wm
);
961 REG_GET_2(DCN_GLOBAL_TTU_CNTL
,
962 MIN_TTU_VBLANK
, &ttu_attr
->min_ttu_vblank
,
963 QoS_LEVEL_FLIP
, &ttu_attr
->qos_level_flip
);
965 /* TTU - per luma/chroma */
966 /* Assumed surf0 is luma and 1 is chroma */
968 REG_GET_3(DCN_SURF0_TTU_CNTL0
,
969 REFCYC_PER_REQ_DELIVERY
, &ttu_attr
->refcyc_per_req_delivery_l
,
970 QoS_LEVEL_FIXED
, &ttu_attr
->qos_level_fixed_l
,
971 QoS_RAMP_DISABLE
, &ttu_attr
->qos_ramp_disable_l
);
973 REG_GET(DCN_SURF0_TTU_CNTL1
,
974 REFCYC_PER_REQ_DELIVERY_PRE
,
975 &ttu_attr
->refcyc_per_req_delivery_pre_l
);
977 REG_GET_3(DCN_SURF1_TTU_CNTL0
,
978 REFCYC_PER_REQ_DELIVERY
, &ttu_attr
->refcyc_per_req_delivery_c
,
979 QoS_LEVEL_FIXED
, &ttu_attr
->qos_level_fixed_c
,
980 QoS_RAMP_DISABLE
, &ttu_attr
->qos_ramp_disable_c
);
982 REG_GET(DCN_SURF1_TTU_CNTL1
,
983 REFCYC_PER_REQ_DELIVERY_PRE
,
984 &ttu_attr
->refcyc_per_req_delivery_pre_c
);
987 REG_GET(DCSURF_SURFACE_CONFIG
,
988 SURFACE_PIXEL_FORMAT
, &s
->pixel_format
);
990 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH
,
991 SURFACE_EARLIEST_INUSE_ADDRESS_HIGH
, &s
->inuse_addr_hi
);
993 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE
,
994 SURFACE_EARLIEST_INUSE_ADDRESS
, &s
->inuse_addr_lo
);
996 REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION
,
997 PRI_VIEWPORT_WIDTH
, &s
->viewport_width
,
998 PRI_VIEWPORT_HEIGHT
, &s
->viewport_height
);
1000 REG_GET_2(DCSURF_SURFACE_CONFIG
,
1001 ROTATION_ANGLE
, &s
->rotation_angle
,
1002 H_MIRROR_EN
, &s
->h_mirror_en
);
1004 REG_GET(DCSURF_TILING_CONFIG
,
1005 SW_MODE
, &s
->sw_mode
);
1007 REG_GET(DCSURF_SURFACE_CONTROL
,
1008 PRIMARY_SURFACE_DCC_EN
, &s
->dcc_en
);
1010 REG_GET_3(DCHUBP_CNTL
,
1011 HUBP_BLANK_EN
, &s
->blank_en
,
1012 HUBP_TTU_DISABLE
, &s
->ttu_disable
,
1013 HUBP_UNDERFLOW_STATUS
, &s
->underflow_status
);
1015 REG_GET(HUBP_CLK_CNTL
,
1016 HUBP_CLOCK_ENABLE
, &s
->clock_en
);
1018 REG_GET(DCN_GLOBAL_TTU_CNTL
,
1019 MIN_TTU_VBLANK
, &s
->min_ttu_vblank
);
1021 REG_GET_2(DCN_TTU_QOS_WM
,
1022 QoS_LEVEL_LOW_WM
, &s
->qos_level_low_wm
,
1023 QoS_LEVEL_HIGH_WM
, &s
->qos_level_high_wm
);
1027 void hubp1_read_state(struct hubp
*hubp
)
1029 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
1030 struct dcn_hubp_state
*s
= &hubp1
->state
;
1031 struct _vcs_dpi_display_rq_regs_st
*rq_regs
= &s
->rq_regs
;
1033 hubp1_read_state_common(hubp
);
1035 REG_GET_8(DCHUBP_REQ_SIZE_CONFIG
,
1036 CHUNK_SIZE
, &rq_regs
->rq_regs_l
.chunk_size
,
1037 MIN_CHUNK_SIZE
, &rq_regs
->rq_regs_l
.min_chunk_size
,
1038 META_CHUNK_SIZE
, &rq_regs
->rq_regs_l
.meta_chunk_size
,
1039 MIN_META_CHUNK_SIZE
, &rq_regs
->rq_regs_l
.min_meta_chunk_size
,
1040 DPTE_GROUP_SIZE
, &rq_regs
->rq_regs_l
.dpte_group_size
,
1041 MPTE_GROUP_SIZE
, &rq_regs
->rq_regs_l
.mpte_group_size
,
1042 SWATH_HEIGHT
, &rq_regs
->rq_regs_l
.swath_height
,
1043 PTE_ROW_HEIGHT_LINEAR
, &rq_regs
->rq_regs_l
.pte_row_height_linear
);
1045 REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C
,
1046 CHUNK_SIZE_C
, &rq_regs
->rq_regs_c
.chunk_size
,
1047 MIN_CHUNK_SIZE_C
, &rq_regs
->rq_regs_c
.min_chunk_size
,
1048 META_CHUNK_SIZE_C
, &rq_regs
->rq_regs_c
.meta_chunk_size
,
1049 MIN_META_CHUNK_SIZE_C
, &rq_regs
->rq_regs_c
.min_meta_chunk_size
,
1050 DPTE_GROUP_SIZE_C
, &rq_regs
->rq_regs_c
.dpte_group_size
,
1051 MPTE_GROUP_SIZE_C
, &rq_regs
->rq_regs_c
.mpte_group_size
,
1052 SWATH_HEIGHT_C
, &rq_regs
->rq_regs_c
.swath_height
,
1053 PTE_ROW_HEIGHT_LINEAR_C
, &rq_regs
->rq_regs_c
.pte_row_height_linear
);
1056 enum cursor_pitch
hubp1_get_cursor_pitch(unsigned int pitch
)
1058 enum cursor_pitch hw_pitch
;
1062 hw_pitch
= CURSOR_PITCH_64_PIXELS
;
1065 hw_pitch
= CURSOR_PITCH_128_PIXELS
;
1068 hw_pitch
= CURSOR_PITCH_256_PIXELS
;
1071 DC_ERR("Invalid cursor pitch of %d. "
1072 "Only 64/128/256 is supported on DCN.\n", pitch
);
1073 hw_pitch
= CURSOR_PITCH_64_PIXELS
;
1079 static enum cursor_lines_per_chunk
hubp1_get_lines_per_chunk(
1080 unsigned int cur_width
,
1081 enum dc_cursor_color_format format
)
1083 enum cursor_lines_per_chunk line_per_chunk
;
1085 if (format
== CURSOR_MODE_MONO
)
1086 /* impl B. expansion in CUR Buffer reader */
1087 line_per_chunk
= CURSOR_LINE_PER_CHUNK_16
;
1088 else if (cur_width
<= 32)
1089 line_per_chunk
= CURSOR_LINE_PER_CHUNK_16
;
1090 else if (cur_width
<= 64)
1091 line_per_chunk
= CURSOR_LINE_PER_CHUNK_8
;
1092 else if (cur_width
<= 128)
1093 line_per_chunk
= CURSOR_LINE_PER_CHUNK_4
;
1095 line_per_chunk
= CURSOR_LINE_PER_CHUNK_2
;
1097 return line_per_chunk
;
1100 void hubp1_cursor_set_attributes(
1102 const struct dc_cursor_attributes
*attr
)
1104 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
1105 enum cursor_pitch hw_pitch
= hubp1_get_cursor_pitch(attr
->pitch
);
1106 enum cursor_lines_per_chunk lpc
= hubp1_get_lines_per_chunk(
1107 attr
->width
, attr
->color_format
);
1109 hubp
->curs_attr
= *attr
;
1111 REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH
,
1112 CURSOR_SURFACE_ADDRESS_HIGH
, attr
->address
.high_part
);
1113 REG_UPDATE(CURSOR_SURFACE_ADDRESS
,
1114 CURSOR_SURFACE_ADDRESS
, attr
->address
.low_part
);
1116 REG_UPDATE_2(CURSOR_SIZE
,
1117 CURSOR_WIDTH
, attr
->width
,
1118 CURSOR_HEIGHT
, attr
->height
);
1120 REG_UPDATE_3(CURSOR_CONTROL
,
1121 CURSOR_MODE
, attr
->color_format
,
1122 CURSOR_PITCH
, hw_pitch
,
1123 CURSOR_LINES_PER_CHUNK
, lpc
);
1125 REG_SET_2(CURSOR_SETTINS
, 0,
1126 /* no shift of the cursor HDL schedule */
1127 CURSOR0_DST_Y_OFFSET
, 0,
1128 /* used to shift the cursor chunk request deadline */
1129 CURSOR0_CHUNK_HDL_ADJUST
, 3);
1132 void hubp1_cursor_set_position(
1134 const struct dc_cursor_position
*pos
,
1135 const struct dc_cursor_mi_param
*param
)
1137 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
1138 int src_x_offset
= pos
->x
- pos
->x_hotspot
- param
->viewport
.x
;
1139 int src_y_offset
= pos
->y
- pos
->y_hotspot
- param
->viewport
.y
;
1140 int x_hotspot
= pos
->x_hotspot
;
1141 int y_hotspot
= pos
->y_hotspot
;
1142 uint32_t dst_x_offset
;
1143 uint32_t cur_en
= pos
->enable
? 1 : 0;
1146 * Guard aganst cursor_set_position() from being called with invalid
1149 * TODO: Look at combining cursor_set_position() and
1150 * cursor_set_attributes() into cursor_update()
1152 if (hubp
->curs_attr
.address
.quad_part
== 0)
1155 if (param
->rotation
== ROTATION_ANGLE_90
|| param
->rotation
== ROTATION_ANGLE_270
) {
1156 src_x_offset
= pos
->y
- pos
->y_hotspot
- param
->viewport
.x
;
1157 y_hotspot
= pos
->x_hotspot
;
1158 x_hotspot
= pos
->y_hotspot
;
1161 if (param
->mirror
) {
1162 x_hotspot
= param
->viewport
.width
- x_hotspot
;
1163 src_x_offset
= param
->viewport
.x
+ param
->viewport
.width
- src_x_offset
;
1166 dst_x_offset
= (src_x_offset
>= 0) ? src_x_offset
: 0;
1167 dst_x_offset
*= param
->ref_clk_khz
;
1168 dst_x_offset
/= param
->pixel_clk_khz
;
1170 ASSERT(param
->h_scale_ratio
.value
);
1172 if (param
->h_scale_ratio
.value
)
1173 dst_x_offset
= dc_fixpt_floor(dc_fixpt_div(
1174 dc_fixpt_from_int(dst_x_offset
),
1175 param
->h_scale_ratio
));
1177 if (src_x_offset
>= (int)param
->viewport
.width
)
1178 cur_en
= 0; /* not visible beyond right edge*/
1180 if (src_x_offset
+ (int)hubp
->curs_attr
.width
<= 0)
1181 cur_en
= 0; /* not visible beyond left edge*/
1183 if (src_y_offset
>= (int)param
->viewport
.height
)
1184 cur_en
= 0; /* not visible beyond bottom edge*/
1186 if (src_y_offset
+ (int)hubp
->curs_attr
.height
<= 0)
1187 cur_en
= 0; /* not visible beyond top edge*/
1189 if (cur_en
&& REG_READ(CURSOR_SURFACE_ADDRESS
) == 0)
1190 hubp
->funcs
->set_cursor_attributes(hubp
, &hubp
->curs_attr
);
1192 REG_UPDATE(CURSOR_CONTROL
,
1193 CURSOR_ENABLE
, cur_en
);
1195 REG_SET_2(CURSOR_POSITION
, 0,
1196 CURSOR_X_POSITION
, pos
->x
,
1197 CURSOR_Y_POSITION
, pos
->y
);
1199 REG_SET_2(CURSOR_HOT_SPOT
, 0,
1200 CURSOR_HOT_SPOT_X
, x_hotspot
,
1201 CURSOR_HOT_SPOT_Y
, y_hotspot
);
1203 REG_SET(CURSOR_DST_OFFSET
, 0,
1204 CURSOR_DST_X_OFFSET
, dst_x_offset
);
1205 /* TODO Handle surface pixel formats other than 4:4:4 */
1208 void hubp1_clk_cntl(struct hubp
*hubp
, bool enable
)
1210 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
1211 uint32_t clk_enable
= enable
? 1 : 0;
1213 REG_UPDATE(HUBP_CLK_CNTL
, HUBP_CLOCK_ENABLE
, clk_enable
);
1216 void hubp1_vtg_sel(struct hubp
*hubp
, uint32_t otg_inst
)
1218 struct dcn10_hubp
*hubp1
= TO_DCN10_HUBP(hubp
);
1220 REG_UPDATE(DCHUBP_CNTL
, HUBP_VTG_SEL
, otg_inst
);
1223 void hubp1_init(struct hubp
*hubp
)
1227 static const struct hubp_funcs dcn10_hubp_funcs
= {
1228 .hubp_program_surface_flip_and_addr
=
1229 hubp1_program_surface_flip_and_addr
,
1230 .hubp_program_surface_config
=
1231 hubp1_program_surface_config
,
1232 .hubp_is_flip_pending
= hubp1_is_flip_pending
,
1233 .hubp_setup
= hubp1_setup
,
1234 .hubp_setup_interdependent
= hubp1_setup_interdependent
,
1235 .hubp_set_vm_system_aperture_settings
= hubp1_set_vm_system_aperture_settings
,
1236 .hubp_set_vm_context0_settings
= hubp1_set_vm_context0_settings
,
1237 .set_blank
= hubp1_set_blank
,
1238 .dcc_control
= hubp1_dcc_control
,
1239 .mem_program_viewport
= min_set_viewport
,
1240 .set_hubp_blank_en
= hubp1_set_hubp_blank_en
,
1241 .set_cursor_attributes
= hubp1_cursor_set_attributes
,
1242 .set_cursor_position
= hubp1_cursor_set_position
,
1243 .hubp_disconnect
= hubp1_disconnect
,
1244 .hubp_clk_cntl
= hubp1_clk_cntl
,
1245 .hubp_vtg_sel
= hubp1_vtg_sel
,
1246 .hubp_read_state
= hubp1_read_state
,
1247 .hubp_clear_underflow
= hubp1_clear_underflow
,
1248 .hubp_disable_control
= hubp1_disable_control
,
1249 .hubp_get_underflow_status
= hubp1_get_underflow_status
,
1250 .hubp_init
= hubp1_init
,
1252 .dmdata_set_attributes
= NULL
,
1253 .dmdata_load
= NULL
,
1256 /*****************************************/
1257 /* Constructor, Destructor */
1258 /*****************************************/
1260 void dcn10_hubp_construct(
1261 struct dcn10_hubp
*hubp1
,
1262 struct dc_context
*ctx
,
1264 const struct dcn_mi_registers
*hubp_regs
,
1265 const struct dcn_mi_shift
*hubp_shift
,
1266 const struct dcn_mi_mask
*hubp_mask
)
1268 hubp1
->base
.funcs
= &dcn10_hubp_funcs
;
1269 hubp1
->base
.ctx
= ctx
;
1270 hubp1
->hubp_regs
= hubp_regs
;
1271 hubp1
->hubp_shift
= hubp_shift
;
1272 hubp1
->hubp_mask
= hubp_mask
;
1273 hubp1
->base
.inst
= inst
;
1274 hubp1
->base
.opp_id
= OPP_ID_INVALID
;
1275 hubp1
->base
.mpcc_id
= 0xf;