0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include "dm_services.h"
0026 #include "dce_calcs.h"
0027 #include "reg_helper.h"
0028 #include "basics/conversion.h"
0029 #include "dcn10_hubp.h"
0030
0031 #define REG(reg)\
0032 hubp1->hubp_regs->reg
0033
0034 #define CTX \
0035 hubp1->base.ctx
0036
0037 #undef FN
0038 #define FN(reg_name, field_name) \
0039 hubp1->hubp_shift->field_name, hubp1->hubp_mask->field_name
0040
0041 void hubp1_set_blank(struct hubp *hubp, bool blank)
0042 {
0043 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0044 uint32_t blank_en = blank ? 1 : 0;
0045
0046 REG_UPDATE_2(DCHUBP_CNTL,
0047 HUBP_BLANK_EN, blank_en,
0048 HUBP_TTU_DISABLE, blank_en);
0049
0050 if (blank) {
0051 uint32_t reg_val = REG_READ(DCHUBP_CNTL);
0052
0053 if (reg_val) {
0054
0055
0056
0057
0058
0059
0060 REG_WAIT(DCHUBP_CNTL,
0061 HUBP_NO_OUTSTANDING_REQ, 1,
0062 1, 200);
0063 }
0064
0065 hubp->mpcc_id = 0xf;
0066 hubp->opp_id = OPP_ID_INVALID;
0067 }
0068 }
0069
0070 static void hubp1_disconnect(struct hubp *hubp)
0071 {
0072 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0073
0074 REG_UPDATE(DCHUBP_CNTL,
0075 HUBP_TTU_DISABLE, 1);
0076
0077 REG_UPDATE(CURSOR_CONTROL,
0078 CURSOR_ENABLE, 0);
0079 }
0080
0081 static void hubp1_disable_control(struct hubp *hubp, bool disable_hubp)
0082 {
0083 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0084 uint32_t disable = disable_hubp ? 1 : 0;
0085
0086 REG_UPDATE(DCHUBP_CNTL,
0087 HUBP_DISABLE, disable);
0088 }
0089
0090 static unsigned int hubp1_get_underflow_status(struct hubp *hubp)
0091 {
0092 uint32_t hubp_underflow = 0;
0093 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0094
0095 REG_GET(DCHUBP_CNTL,
0096 HUBP_UNDERFLOW_STATUS,
0097 &hubp_underflow);
0098
0099 return hubp_underflow;
0100 }
0101
0102
0103 void hubp1_clear_underflow(struct hubp *hubp)
0104 {
0105 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0106
0107 REG_UPDATE(DCHUBP_CNTL, HUBP_UNDERFLOW_CLEAR, 1);
0108 }
0109
0110 static void hubp1_set_hubp_blank_en(struct hubp *hubp, bool blank)
0111 {
0112 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0113 uint32_t blank_en = blank ? 1 : 0;
0114
0115 REG_UPDATE(DCHUBP_CNTL, HUBP_BLANK_EN, blank_en);
0116 }
0117
0118 void hubp1_vready_workaround(struct hubp *hubp,
0119 struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
0120 {
0121 uint32_t value = 0;
0122 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0123
0124
0125 value = REG_READ(HUBPREQ_DEBUG_DB);
0126
0127
0128 value |= 0x100;
0129 value &= ~0x1000;
0130
0131 if ((pipe_dest->vstartup_start - 2*(pipe_dest->vready_offset+pipe_dest->vupdate_width
0132 + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) {
0133
0134
0135 value |= 0x1000;
0136 }
0137
0138 REG_WRITE(HUBPREQ_DEBUG_DB, value);
0139 }
0140
0141 void hubp1_program_tiling(
0142 struct hubp *hubp,
0143 const union dc_tiling_info *info,
0144 const enum surface_pixel_format pixel_format)
0145 {
0146 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0147
0148 REG_UPDATE_6(DCSURF_ADDR_CONFIG,
0149 NUM_PIPES, log_2(info->gfx9.num_pipes),
0150 NUM_BANKS, log_2(info->gfx9.num_banks),
0151 PIPE_INTERLEAVE, info->gfx9.pipe_interleave,
0152 NUM_SE, log_2(info->gfx9.num_shader_engines),
0153 NUM_RB_PER_SE, log_2(info->gfx9.num_rb_per_se),
0154 MAX_COMPRESSED_FRAGS, log_2(info->gfx9.max_compressed_frags));
0155
0156 REG_UPDATE_4(DCSURF_TILING_CONFIG,
0157 SW_MODE, info->gfx9.swizzle,
0158 META_LINEAR, info->gfx9.meta_linear,
0159 RB_ALIGNED, info->gfx9.rb_aligned,
0160 PIPE_ALIGNED, info->gfx9.pipe_aligned);
0161 }
0162
0163 void hubp1_program_size(
0164 struct hubp *hubp,
0165 enum surface_pixel_format format,
0166 const struct plane_size *plane_size,
0167 struct dc_plane_dcc_param *dcc)
0168 {
0169 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0170 uint32_t pitch, meta_pitch, pitch_c, meta_pitch_c;
0171
0172
0173
0174
0175 if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END) {
0176 ASSERT(plane_size->chroma_pitch != 0);
0177
0178
0179 pitch = plane_size->surface_pitch - 1;
0180 meta_pitch = dcc->meta_pitch - 1;
0181 pitch_c = plane_size->chroma_pitch - 1;
0182 meta_pitch_c = dcc->meta_pitch_c - 1;
0183 } else {
0184 pitch = plane_size->surface_pitch - 1;
0185 meta_pitch = dcc->meta_pitch - 1;
0186 pitch_c = 0;
0187 meta_pitch_c = 0;
0188 }
0189
0190 if (!dcc->enable) {
0191 meta_pitch = 0;
0192 meta_pitch_c = 0;
0193 }
0194
0195 REG_UPDATE_2(DCSURF_SURFACE_PITCH,
0196 PITCH, pitch, META_PITCH, meta_pitch);
0197
0198 if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
0199 REG_UPDATE_2(DCSURF_SURFACE_PITCH_C,
0200 PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c);
0201 }
0202
0203 void hubp1_program_rotation(
0204 struct hubp *hubp,
0205 enum dc_rotation_angle rotation,
0206 bool horizontal_mirror)
0207 {
0208 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0209 uint32_t mirror;
0210
0211
0212 if (horizontal_mirror)
0213 mirror = 1;
0214 else
0215 mirror = 0;
0216
0217
0218 if (rotation == ROTATION_ANGLE_0)
0219 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
0220 ROTATION_ANGLE, 0,
0221 H_MIRROR_EN, mirror);
0222 else if (rotation == ROTATION_ANGLE_90)
0223 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
0224 ROTATION_ANGLE, 1,
0225 H_MIRROR_EN, mirror);
0226 else if (rotation == ROTATION_ANGLE_180)
0227 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
0228 ROTATION_ANGLE, 2,
0229 H_MIRROR_EN, mirror);
0230 else if (rotation == ROTATION_ANGLE_270)
0231 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
0232 ROTATION_ANGLE, 3,
0233 H_MIRROR_EN, mirror);
0234 }
0235
0236 void hubp1_program_pixel_format(
0237 struct hubp *hubp,
0238 enum surface_pixel_format format)
0239 {
0240 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0241 uint32_t red_bar = 3;
0242 uint32_t blue_bar = 2;
0243
0244
0245 if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
0246 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
0247 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
0248 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
0249 || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
0250 red_bar = 2;
0251 blue_bar = 3;
0252 }
0253
0254 REG_UPDATE_2(HUBPRET_CONTROL,
0255 CROSSBAR_SRC_CB_B, blue_bar,
0256 CROSSBAR_SRC_CR_R, red_bar);
0257
0258
0259
0260 switch (format) {
0261 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
0262 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0263 SURFACE_PIXEL_FORMAT, 1);
0264 break;
0265 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
0266 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0267 SURFACE_PIXEL_FORMAT, 3);
0268 break;
0269 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
0270 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
0271 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0272 SURFACE_PIXEL_FORMAT, 8);
0273 break;
0274 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
0275 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
0276 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
0277 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0278 SURFACE_PIXEL_FORMAT, 10);
0279 break;
0280 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
0281 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
0282 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0283 SURFACE_PIXEL_FORMAT, 26);
0284 break;
0285 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
0286 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
0287 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0288 SURFACE_PIXEL_FORMAT, 24);
0289 break;
0290
0291 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
0292 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0293 SURFACE_PIXEL_FORMAT, 65);
0294 break;
0295 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
0296 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0297 SURFACE_PIXEL_FORMAT, 64);
0298 break;
0299 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
0300 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0301 SURFACE_PIXEL_FORMAT, 67);
0302 break;
0303 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
0304 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0305 SURFACE_PIXEL_FORMAT, 66);
0306 break;
0307 case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
0308 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0309 SURFACE_PIXEL_FORMAT, 12);
0310 break;
0311 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
0312 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0313 SURFACE_PIXEL_FORMAT, 112);
0314 break;
0315 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
0316 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0317 SURFACE_PIXEL_FORMAT, 113);
0318 break;
0319 case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
0320 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0321 SURFACE_PIXEL_FORMAT, 114);
0322 break;
0323 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
0324 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0325 SURFACE_PIXEL_FORMAT, 118);
0326 break;
0327 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
0328 REG_UPDATE(DCSURF_SURFACE_CONFIG,
0329 SURFACE_PIXEL_FORMAT, 119);
0330 break;
0331 case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
0332 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
0333 SURFACE_PIXEL_FORMAT, 116,
0334 ALPHA_PLANE_EN, 0);
0335 break;
0336 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
0337 REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
0338 SURFACE_PIXEL_FORMAT, 116,
0339 ALPHA_PLANE_EN, 1);
0340 break;
0341 default:
0342 BREAK_TO_DEBUGGER();
0343 break;
0344 }
0345
0346
0347 }
0348
0349 bool hubp1_program_surface_flip_and_addr(
0350 struct hubp *hubp,
0351 const struct dc_plane_address *address,
0352 bool flip_immediate)
0353 {
0354 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0355
0356
0357
0358 REG_UPDATE(DCSURF_FLIP_CONTROL,
0359 SURFACE_FLIP_TYPE, flip_immediate);
0360
0361
0362 if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) {
0363 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x1);
0364 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1);
0365
0366 } else {
0367
0368 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0);
0369 REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0);
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379 switch (address->type) {
0380 case PLN_ADDR_TYPE_GRAPHICS:
0381
0382
0383
0384
0385
0386
0387
0388 if (address->grph.addr.quad_part == 0)
0389 break;
0390
0391 REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
0392 PRIMARY_SURFACE_TMZ, address->tmz_surface,
0393 PRIMARY_META_SURFACE_TMZ, address->tmz_surface);
0394
0395 if (address->grph.meta_addr.quad_part != 0) {
0396 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
0397 PRIMARY_META_SURFACE_ADDRESS_HIGH,
0398 address->grph.meta_addr.high_part);
0399
0400 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
0401 PRIMARY_META_SURFACE_ADDRESS,
0402 address->grph.meta_addr.low_part);
0403 }
0404
0405 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
0406 PRIMARY_SURFACE_ADDRESS_HIGH,
0407 address->grph.addr.high_part);
0408
0409 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
0410 PRIMARY_SURFACE_ADDRESS,
0411 address->grph.addr.low_part);
0412 break;
0413 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
0414 if (address->video_progressive.luma_addr.quad_part == 0
0415 || address->video_progressive.chroma_addr.quad_part == 0)
0416 break;
0417
0418 REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
0419 PRIMARY_SURFACE_TMZ, address->tmz_surface,
0420 PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
0421 PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
0422 PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface);
0423
0424 if (address->video_progressive.luma_meta_addr.quad_part != 0) {
0425 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0,
0426 PRIMARY_META_SURFACE_ADDRESS_HIGH_C,
0427 address->video_progressive.chroma_meta_addr.high_part);
0428
0429 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0,
0430 PRIMARY_META_SURFACE_ADDRESS_C,
0431 address->video_progressive.chroma_meta_addr.low_part);
0432
0433 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
0434 PRIMARY_META_SURFACE_ADDRESS_HIGH,
0435 address->video_progressive.luma_meta_addr.high_part);
0436
0437 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
0438 PRIMARY_META_SURFACE_ADDRESS,
0439 address->video_progressive.luma_meta_addr.low_part);
0440 }
0441
0442 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
0443 PRIMARY_SURFACE_ADDRESS_HIGH_C,
0444 address->video_progressive.chroma_addr.high_part);
0445
0446 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
0447 PRIMARY_SURFACE_ADDRESS_C,
0448 address->video_progressive.chroma_addr.low_part);
0449
0450 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
0451 PRIMARY_SURFACE_ADDRESS_HIGH,
0452 address->video_progressive.luma_addr.high_part);
0453
0454 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
0455 PRIMARY_SURFACE_ADDRESS,
0456 address->video_progressive.luma_addr.low_part);
0457 break;
0458 case PLN_ADDR_TYPE_GRPH_STEREO:
0459 if (address->grph_stereo.left_addr.quad_part == 0)
0460 break;
0461 if (address->grph_stereo.right_addr.quad_part == 0)
0462 break;
0463
0464 REG_UPDATE_8(DCSURF_SURFACE_CONTROL,
0465 PRIMARY_SURFACE_TMZ, address->tmz_surface,
0466 PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
0467 PRIMARY_META_SURFACE_TMZ, address->tmz_surface,
0468 PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface,
0469 SECONDARY_SURFACE_TMZ, address->tmz_surface,
0470 SECONDARY_SURFACE_TMZ_C, address->tmz_surface,
0471 SECONDARY_META_SURFACE_TMZ, address->tmz_surface,
0472 SECONDARY_META_SURFACE_TMZ_C, address->tmz_surface);
0473
0474 if (address->grph_stereo.right_meta_addr.quad_part != 0) {
0475
0476 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0,
0477 SECONDARY_META_SURFACE_ADDRESS_HIGH,
0478 address->grph_stereo.right_meta_addr.high_part);
0479
0480 REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0,
0481 SECONDARY_META_SURFACE_ADDRESS,
0482 address->grph_stereo.right_meta_addr.low_part);
0483 }
0484 if (address->grph_stereo.left_meta_addr.quad_part != 0) {
0485
0486 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0,
0487 PRIMARY_META_SURFACE_ADDRESS_HIGH,
0488 address->grph_stereo.left_meta_addr.high_part);
0489
0490 REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0,
0491 PRIMARY_META_SURFACE_ADDRESS,
0492 address->grph_stereo.left_meta_addr.low_part);
0493 }
0494
0495 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
0496 SECONDARY_SURFACE_ADDRESS_HIGH,
0497 address->grph_stereo.right_addr.high_part);
0498
0499 REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
0500 SECONDARY_SURFACE_ADDRESS,
0501 address->grph_stereo.right_addr.low_part);
0502
0503 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
0504 PRIMARY_SURFACE_ADDRESS_HIGH,
0505 address->grph_stereo.left_addr.high_part);
0506
0507 REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
0508 PRIMARY_SURFACE_ADDRESS,
0509 address->grph_stereo.left_addr.low_part);
0510 break;
0511 default:
0512 BREAK_TO_DEBUGGER();
0513 break;
0514 }
0515
0516 hubp->request_address = *address;
0517
0518 return true;
0519 }
0520
0521 void hubp1_dcc_control(struct hubp *hubp, bool enable,
0522 enum hubp_ind_block_size independent_64b_blks)
0523 {
0524 uint32_t dcc_en = enable ? 1 : 0;
0525 uint32_t dcc_ind_64b_blk = independent_64b_blks ? 1 : 0;
0526 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0527
0528 REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
0529 PRIMARY_SURFACE_DCC_EN, dcc_en,
0530 PRIMARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk,
0531 SECONDARY_SURFACE_DCC_EN, dcc_en,
0532 SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
0533 }
0534
0535 void hubp1_program_surface_config(
0536 struct hubp *hubp,
0537 enum surface_pixel_format format,
0538 union dc_tiling_info *tiling_info,
0539 struct plane_size *plane_size,
0540 enum dc_rotation_angle rotation,
0541 struct dc_plane_dcc_param *dcc,
0542 bool horizontal_mirror,
0543 unsigned int compat_level)
0544 {
0545 hubp1_dcc_control(hubp, dcc->enable, dcc->independent_64b_blks);
0546 hubp1_program_tiling(hubp, tiling_info, format);
0547 hubp1_program_size(hubp, format, plane_size, dcc);
0548 hubp1_program_rotation(hubp, rotation, horizontal_mirror);
0549 hubp1_program_pixel_format(hubp, format);
0550 }
0551
0552 void hubp1_program_requestor(
0553 struct hubp *hubp,
0554 struct _vcs_dpi_display_rq_regs_st *rq_regs)
0555 {
0556 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0557
0558 REG_UPDATE(HUBPRET_CONTROL,
0559 DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
0560 REG_SET_4(DCN_EXPANSION_MODE, 0,
0561 DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode,
0562 PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode,
0563 MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode,
0564 CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode);
0565 REG_SET_8(DCHUBP_REQ_SIZE_CONFIG, 0,
0566 CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size,
0567 MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size,
0568 META_CHUNK_SIZE, rq_regs->rq_regs_l.meta_chunk_size,
0569 MIN_META_CHUNK_SIZE, rq_regs->rq_regs_l.min_meta_chunk_size,
0570 DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size,
0571 MPTE_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size,
0572 SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height,
0573 PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear);
0574 REG_SET_8(DCHUBP_REQ_SIZE_CONFIG_C, 0,
0575 CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size,
0576 MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size,
0577 META_CHUNK_SIZE_C, rq_regs->rq_regs_c.meta_chunk_size,
0578 MIN_META_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_meta_chunk_size,
0579 DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size,
0580 MPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.mpte_group_size,
0581 SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height,
0582 PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear);
0583 }
0584
0585
0586 void hubp1_program_deadline(
0587 struct hubp *hubp,
0588 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
0589 struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
0590 {
0591 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0592
0593
0594 REG_SET_2(BLANK_OFFSET_0, 0,
0595 REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end,
0596 DLG_V_BLANK_END, dlg_attr->dlg_vblank_end);
0597
0598 REG_SET(BLANK_OFFSET_1, 0,
0599 MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start);
0600
0601 REG_SET(DST_DIMENSIONS, 0,
0602 REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal);
0603
0604 REG_SET_2(DST_AFTER_SCALER, 0,
0605 REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler,
0606 DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler);
0607
0608 REG_SET(REF_FREQ_TO_PIX_FREQ, 0,
0609 REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq);
0610
0611
0612 REG_SET(VBLANK_PARAMETERS_1, 0,
0613 REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l);
0614
0615 if (REG(NOM_PARAMETERS_0))
0616 REG_SET(NOM_PARAMETERS_0, 0,
0617 DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
0618
0619 if (REG(NOM_PARAMETERS_1))
0620 REG_SET(NOM_PARAMETERS_1, 0,
0621 REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
0622
0623 REG_SET(NOM_PARAMETERS_4, 0,
0624 DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
0625
0626 REG_SET(NOM_PARAMETERS_5, 0,
0627 REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l);
0628
0629 REG_SET_2(PER_LINE_DELIVERY, 0,
0630 REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l,
0631 REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c);
0632
0633 REG_SET(VBLANK_PARAMETERS_2, 0,
0634 REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c);
0635
0636 if (REG(NOM_PARAMETERS_2))
0637 REG_SET(NOM_PARAMETERS_2, 0,
0638 DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
0639
0640 if (REG(NOM_PARAMETERS_3))
0641 REG_SET(NOM_PARAMETERS_3, 0,
0642 REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
0643
0644 REG_SET(NOM_PARAMETERS_6, 0,
0645 DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
0646
0647 REG_SET(NOM_PARAMETERS_7, 0,
0648 REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c);
0649
0650
0651 REG_SET_2(DCN_TTU_QOS_WM, 0,
0652 QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm,
0653 QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm);
0654
0655
0656
0657
0658 REG_SET_3(DCN_SURF0_TTU_CNTL0, 0,
0659 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l,
0660 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l,
0661 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l);
0662
0663 REG_SET_3(DCN_SURF1_TTU_CNTL0, 0,
0664 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c,
0665 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c,
0666 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c);
0667
0668 REG_SET_3(DCN_CUR0_TTU_CNTL0, 0,
0669 REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0,
0670 QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0,
0671 QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0);
0672 }
0673
0674 static void hubp1_setup(
0675 struct hubp *hubp,
0676 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
0677 struct _vcs_dpi_display_ttu_regs_st *ttu_attr,
0678 struct _vcs_dpi_display_rq_regs_st *rq_regs,
0679 struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest)
0680 {
0681
0682
0683
0684 hubp1_program_requestor(hubp, rq_regs);
0685 hubp1_program_deadline(hubp, dlg_attr, ttu_attr);
0686 hubp1_vready_workaround(hubp, pipe_dest);
0687 }
0688
0689 static void hubp1_setup_interdependent(
0690 struct hubp *hubp,
0691 struct _vcs_dpi_display_dlg_regs_st *dlg_attr,
0692 struct _vcs_dpi_display_ttu_regs_st *ttu_attr)
0693 {
0694 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0695
0696 REG_SET_2(PREFETCH_SETTINS, 0,
0697 DST_Y_PREFETCH, dlg_attr->dst_y_prefetch,
0698 VRATIO_PREFETCH, dlg_attr->vratio_prefetch);
0699
0700 REG_SET(PREFETCH_SETTINS_C, 0,
0701 VRATIO_PREFETCH_C, dlg_attr->vratio_prefetch_c);
0702
0703 REG_SET_2(VBLANK_PARAMETERS_0, 0,
0704 DST_Y_PER_VM_VBLANK, dlg_attr->dst_y_per_vm_vblank,
0705 DST_Y_PER_ROW_VBLANK, dlg_attr->dst_y_per_row_vblank);
0706
0707 REG_SET(VBLANK_PARAMETERS_3, 0,
0708 REFCYC_PER_META_CHUNK_VBLANK_L, dlg_attr->refcyc_per_meta_chunk_vblank_l);
0709
0710 REG_SET(VBLANK_PARAMETERS_4, 0,
0711 REFCYC_PER_META_CHUNK_VBLANK_C, dlg_attr->refcyc_per_meta_chunk_vblank_c);
0712
0713 REG_SET_2(PER_LINE_DELIVERY_PRE, 0,
0714 REFCYC_PER_LINE_DELIVERY_PRE_L, dlg_attr->refcyc_per_line_delivery_pre_l,
0715 REFCYC_PER_LINE_DELIVERY_PRE_C, dlg_attr->refcyc_per_line_delivery_pre_c);
0716
0717 REG_SET(DCN_SURF0_TTU_CNTL1, 0,
0718 REFCYC_PER_REQ_DELIVERY_PRE,
0719 ttu_attr->refcyc_per_req_delivery_pre_l);
0720 REG_SET(DCN_SURF1_TTU_CNTL1, 0,
0721 REFCYC_PER_REQ_DELIVERY_PRE,
0722 ttu_attr->refcyc_per_req_delivery_pre_c);
0723 REG_SET(DCN_CUR0_TTU_CNTL1, 0,
0724 REFCYC_PER_REQ_DELIVERY_PRE, ttu_attr->refcyc_per_req_delivery_pre_cur0);
0725
0726 REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0,
0727 MIN_TTU_VBLANK, ttu_attr->min_ttu_vblank,
0728 QoS_LEVEL_FLIP, ttu_attr->qos_level_flip);
0729 }
0730
0731 bool hubp1_is_flip_pending(struct hubp *hubp)
0732 {
0733 uint32_t flip_pending = 0;
0734 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0735 struct dc_plane_address earliest_inuse_address;
0736
0737 if (hubp && hubp->power_gated)
0738 return false;
0739
0740 REG_GET(DCSURF_FLIP_CONTROL,
0741 SURFACE_FLIP_PENDING, &flip_pending);
0742
0743 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE,
0744 SURFACE_EARLIEST_INUSE_ADDRESS, &earliest_inuse_address.grph.addr.low_part);
0745
0746 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
0747 SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &earliest_inuse_address.grph.addr.high_part);
0748
0749 if (flip_pending)
0750 return true;
0751
0752 if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
0753 return true;
0754
0755 return false;
0756 }
0757
0758 uint32_t aperture_default_system = 1;
0759 uint32_t context0_default_system;
0760
0761 static void hubp1_set_vm_system_aperture_settings(struct hubp *hubp,
0762 struct vm_system_aperture_param *apt)
0763 {
0764 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0765 PHYSICAL_ADDRESS_LOC mc_vm_apt_default;
0766 PHYSICAL_ADDRESS_LOC mc_vm_apt_low;
0767 PHYSICAL_ADDRESS_LOC mc_vm_apt_high;
0768
0769 mc_vm_apt_default.quad_part = apt->sys_default.quad_part >> 12;
0770 mc_vm_apt_low.quad_part = apt->sys_low.quad_part >> 12;
0771 mc_vm_apt_high.quad_part = apt->sys_high.quad_part >> 12;
0772
0773 REG_SET_2(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 0,
0774 MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, aperture_default_system,
0775 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mc_vm_apt_default.high_part);
0776 REG_SET(DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 0,
0777 MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mc_vm_apt_default.low_part);
0778
0779 REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, 0,
0780 MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, mc_vm_apt_low.high_part);
0781 REG_SET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, 0,
0782 MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, mc_vm_apt_low.low_part);
0783
0784 REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, 0,
0785 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, mc_vm_apt_high.high_part);
0786 REG_SET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, 0,
0787 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, mc_vm_apt_high.low_part);
0788 }
0789
0790 static void hubp1_set_vm_context0_settings(struct hubp *hubp,
0791 const struct vm_context0_param *vm0)
0792 {
0793 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0794
0795 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, 0,
0796 VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_MSB, vm0->pte_base.high_part);
0797 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, 0,
0798 VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LSB, vm0->pte_base.low_part);
0799
0800
0801 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, 0,
0802 VM_CONTEXT0_PAGE_TABLE_START_ADDR_MSB, vm0->pte_start.high_part);
0803 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, 0,
0804 VM_CONTEXT0_PAGE_TABLE_START_ADDR_LSB, vm0->pte_start.low_part);
0805
0806
0807 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, 0,
0808 VM_CONTEXT0_PAGE_TABLE_END_ADDR_MSB, vm0->pte_end.high_part);
0809 REG_SET(DCN_VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, 0,
0810 VM_CONTEXT0_PAGE_TABLE_END_ADDR_LSB, vm0->pte_end.low_part);
0811
0812
0813 REG_SET_2(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, 0,
0814 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_MSB, vm0->fault_default.high_part,
0815 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_SYSTEM, context0_default_system);
0816 REG_SET(DCN_VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, 0,
0817 VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR_LSB, vm0->fault_default.low_part);
0818
0819
0820 REG_SET_2(DCN_VM_MX_L1_TLB_CNTL, 0,
0821 ENABLE_L1_TLB, 1,
0822 SYSTEM_ACCESS_MODE, 3);
0823 }
0824
0825 void min_set_viewport(
0826 struct hubp *hubp,
0827 const struct rect *viewport,
0828 const struct rect *viewport_c)
0829 {
0830 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0831
0832 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
0833 PRI_VIEWPORT_WIDTH, viewport->width,
0834 PRI_VIEWPORT_HEIGHT, viewport->height);
0835
0836 REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0,
0837 PRI_VIEWPORT_X_START, viewport->x,
0838 PRI_VIEWPORT_Y_START, viewport->y);
0839
0840
0841 REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0,
0842 SEC_VIEWPORT_WIDTH, viewport->width,
0843 SEC_VIEWPORT_HEIGHT, viewport->height);
0844
0845 REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0,
0846 SEC_VIEWPORT_X_START, viewport->x,
0847 SEC_VIEWPORT_Y_START, viewport->y);
0848
0849
0850 REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0,
0851 PRI_VIEWPORT_WIDTH_C, viewport_c->width,
0852 PRI_VIEWPORT_HEIGHT_C, viewport_c->height);
0853
0854 REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0,
0855 PRI_VIEWPORT_X_START_C, viewport_c->x,
0856 PRI_VIEWPORT_Y_START_C, viewport_c->y);
0857
0858 REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION_C, 0,
0859 SEC_VIEWPORT_WIDTH_C, viewport_c->width,
0860 SEC_VIEWPORT_HEIGHT_C, viewport_c->height);
0861
0862 REG_SET_2(DCSURF_SEC_VIEWPORT_START_C, 0,
0863 SEC_VIEWPORT_X_START_C, viewport_c->x,
0864 SEC_VIEWPORT_Y_START_C, viewport_c->y);
0865 }
0866
0867 void hubp1_read_state_common(struct hubp *hubp)
0868 {
0869 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
0870 struct dcn_hubp_state *s = &hubp1->state;
0871 struct _vcs_dpi_display_dlg_regs_st *dlg_attr = &s->dlg_attr;
0872 struct _vcs_dpi_display_ttu_regs_st *ttu_attr = &s->ttu_attr;
0873 struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
0874 uint32_t aperture_low_msb, aperture_low_lsb;
0875 uint32_t aperture_high_msb, aperture_high_lsb;
0876
0877
0878 REG_GET(HUBPRET_CONTROL,
0879 DET_BUF_PLANE1_BASE_ADDRESS, &rq_regs->plane1_base_address);
0880 REG_GET_4(DCN_EXPANSION_MODE,
0881 DRQ_EXPANSION_MODE, &rq_regs->drq_expansion_mode,
0882 PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode,
0883 MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode,
0884 CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode);
0885
0886 REG_GET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_MSB,
0887 MC_VM_SYSTEM_APERTURE_LOW_ADDR_MSB, &aperture_low_msb);
0888
0889 REG_GET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR_LSB,
0890 MC_VM_SYSTEM_APERTURE_LOW_ADDR_LSB, &aperture_low_lsb);
0891
0892 REG_GET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB,
0893 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, &aperture_high_msb);
0894
0895 REG_GET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB,
0896 MC_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, &aperture_high_lsb);
0897
0898
0899 rq_regs->aperture_low_addr = (aperture_low_msb << 26) | (aperture_low_lsb >> 6);
0900 rq_regs->aperture_high_addr = (aperture_high_msb << 26) | (aperture_high_lsb >> 6);
0901
0902
0903 REG_GET_2(BLANK_OFFSET_0,
0904 REFCYC_H_BLANK_END, &dlg_attr->refcyc_h_blank_end,
0905 DLG_V_BLANK_END, &dlg_attr->dlg_vblank_end);
0906
0907 REG_GET(BLANK_OFFSET_1,
0908 MIN_DST_Y_NEXT_START, &dlg_attr->min_dst_y_next_start);
0909
0910 REG_GET(DST_DIMENSIONS,
0911 REFCYC_PER_HTOTAL, &dlg_attr->refcyc_per_htotal);
0912
0913 REG_GET_2(DST_AFTER_SCALER,
0914 REFCYC_X_AFTER_SCALER, &dlg_attr->refcyc_x_after_scaler,
0915 DST_Y_AFTER_SCALER, &dlg_attr->dst_y_after_scaler);
0916
0917 if (REG(PREFETCH_SETTINS))
0918 REG_GET_2(PREFETCH_SETTINS,
0919 DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch,
0920 VRATIO_PREFETCH, &dlg_attr->vratio_prefetch);
0921 else
0922 REG_GET_2(PREFETCH_SETTINGS,
0923 DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch,
0924 VRATIO_PREFETCH, &dlg_attr->vratio_prefetch);
0925
0926 REG_GET_2(VBLANK_PARAMETERS_0,
0927 DST_Y_PER_VM_VBLANK, &dlg_attr->dst_y_per_vm_vblank,
0928 DST_Y_PER_ROW_VBLANK, &dlg_attr->dst_y_per_row_vblank);
0929
0930 REG_GET(REF_FREQ_TO_PIX_FREQ,
0931 REF_FREQ_TO_PIX_FREQ, &dlg_attr->ref_freq_to_pix_freq);
0932
0933
0934 REG_GET(VBLANK_PARAMETERS_1,
0935 REFCYC_PER_PTE_GROUP_VBLANK_L, &dlg_attr->refcyc_per_pte_group_vblank_l);
0936
0937 REG_GET(VBLANK_PARAMETERS_3,
0938 REFCYC_PER_META_CHUNK_VBLANK_L, &dlg_attr->refcyc_per_meta_chunk_vblank_l);
0939
0940 if (REG(NOM_PARAMETERS_0))
0941 REG_GET(NOM_PARAMETERS_0,
0942 DST_Y_PER_PTE_ROW_NOM_L, &dlg_attr->dst_y_per_pte_row_nom_l);
0943
0944 if (REG(NOM_PARAMETERS_1))
0945 REG_GET(NOM_PARAMETERS_1,
0946 REFCYC_PER_PTE_GROUP_NOM_L, &dlg_attr->refcyc_per_pte_group_nom_l);
0947
0948 REG_GET(NOM_PARAMETERS_4,
0949 DST_Y_PER_META_ROW_NOM_L, &dlg_attr->dst_y_per_meta_row_nom_l);
0950
0951 REG_GET(NOM_PARAMETERS_5,
0952 REFCYC_PER_META_CHUNK_NOM_L, &dlg_attr->refcyc_per_meta_chunk_nom_l);
0953
0954 REG_GET_2(PER_LINE_DELIVERY_PRE,
0955 REFCYC_PER_LINE_DELIVERY_PRE_L, &dlg_attr->refcyc_per_line_delivery_pre_l,
0956 REFCYC_PER_LINE_DELIVERY_PRE_C, &dlg_attr->refcyc_per_line_delivery_pre_c);
0957
0958 REG_GET_2(PER_LINE_DELIVERY,
0959 REFCYC_PER_LINE_DELIVERY_L, &dlg_attr->refcyc_per_line_delivery_l,
0960 REFCYC_PER_LINE_DELIVERY_C, &dlg_attr->refcyc_per_line_delivery_c);
0961
0962 if (REG(PREFETCH_SETTINS_C))
0963 REG_GET(PREFETCH_SETTINS_C,
0964 VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c);
0965 else
0966 REG_GET(PREFETCH_SETTINGS_C,
0967 VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c);
0968
0969 REG_GET(VBLANK_PARAMETERS_2,
0970 REFCYC_PER_PTE_GROUP_VBLANK_C, &dlg_attr->refcyc_per_pte_group_vblank_c);
0971
0972 REG_GET(VBLANK_PARAMETERS_4,
0973 REFCYC_PER_META_CHUNK_VBLANK_C, &dlg_attr->refcyc_per_meta_chunk_vblank_c);
0974
0975 if (REG(NOM_PARAMETERS_2))
0976 REG_GET(NOM_PARAMETERS_2,
0977 DST_Y_PER_PTE_ROW_NOM_C, &dlg_attr->dst_y_per_pte_row_nom_c);
0978
0979 if (REG(NOM_PARAMETERS_3))
0980 REG_GET(NOM_PARAMETERS_3,
0981 REFCYC_PER_PTE_GROUP_NOM_C, &dlg_attr->refcyc_per_pte_group_nom_c);
0982
0983 REG_GET(NOM_PARAMETERS_6,
0984 DST_Y_PER_META_ROW_NOM_C, &dlg_attr->dst_y_per_meta_row_nom_c);
0985
0986 REG_GET(NOM_PARAMETERS_7,
0987 REFCYC_PER_META_CHUNK_NOM_C, &dlg_attr->refcyc_per_meta_chunk_nom_c);
0988
0989
0990 REG_GET_2(DCN_TTU_QOS_WM,
0991 QoS_LEVEL_LOW_WM, &ttu_attr->qos_level_low_wm,
0992 QoS_LEVEL_HIGH_WM, &ttu_attr->qos_level_high_wm);
0993
0994 REG_GET_2(DCN_GLOBAL_TTU_CNTL,
0995 MIN_TTU_VBLANK, &ttu_attr->min_ttu_vblank,
0996 QoS_LEVEL_FLIP, &ttu_attr->qos_level_flip);
0997
0998
0999
1000
1001 REG_GET_3(DCN_SURF0_TTU_CNTL0,
1002 REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_l,
1003 QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_l,
1004 QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_l);
1005
1006 REG_GET(DCN_SURF0_TTU_CNTL1,
1007 REFCYC_PER_REQ_DELIVERY_PRE,
1008 &ttu_attr->refcyc_per_req_delivery_pre_l);
1009
1010 REG_GET_3(DCN_SURF1_TTU_CNTL0,
1011 REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_c,
1012 QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_c,
1013 QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_c);
1014
1015 REG_GET(DCN_SURF1_TTU_CNTL1,
1016 REFCYC_PER_REQ_DELIVERY_PRE,
1017 &ttu_attr->refcyc_per_req_delivery_pre_c);
1018
1019
1020 REG_GET(DCSURF_SURFACE_CONFIG,
1021 SURFACE_PIXEL_FORMAT, &s->pixel_format);
1022
1023 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
1024 SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi);
1025
1026 REG_GET(DCSURF_SURFACE_EARLIEST_INUSE,
1027 SURFACE_EARLIEST_INUSE_ADDRESS, &s->inuse_addr_lo);
1028
1029 REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION,
1030 PRI_VIEWPORT_WIDTH, &s->viewport_width,
1031 PRI_VIEWPORT_HEIGHT, &s->viewport_height);
1032
1033 REG_GET_2(DCSURF_SURFACE_CONFIG,
1034 ROTATION_ANGLE, &s->rotation_angle,
1035 H_MIRROR_EN, &s->h_mirror_en);
1036
1037 REG_GET(DCSURF_TILING_CONFIG,
1038 SW_MODE, &s->sw_mode);
1039
1040 REG_GET(DCSURF_SURFACE_CONTROL,
1041 PRIMARY_SURFACE_DCC_EN, &s->dcc_en);
1042
1043 REG_GET_3(DCHUBP_CNTL,
1044 HUBP_BLANK_EN, &s->blank_en,
1045 HUBP_TTU_DISABLE, &s->ttu_disable,
1046 HUBP_UNDERFLOW_STATUS, &s->underflow_status);
1047
1048 REG_GET(HUBP_CLK_CNTL,
1049 HUBP_CLOCK_ENABLE, &s->clock_en);
1050
1051 REG_GET(DCN_GLOBAL_TTU_CNTL,
1052 MIN_TTU_VBLANK, &s->min_ttu_vblank);
1053
1054 REG_GET_2(DCN_TTU_QOS_WM,
1055 QoS_LEVEL_LOW_WM, &s->qos_level_low_wm,
1056 QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
1057
1058 REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS,
1059 PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_lo);
1060
1061 REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH,
1062 PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_hi);
1063
1064 REG_GET(DCSURF_PRIMARY_META_SURFACE_ADDRESS,
1065 PRIMARY_META_SURFACE_ADDRESS, &s->primary_meta_addr_lo);
1066
1067 REG_GET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH,
1068 PRIMARY_META_SURFACE_ADDRESS, &s->primary_meta_addr_hi);
1069 }
1070
1071 void hubp1_read_state(struct hubp *hubp)
1072 {
1073 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1074 struct dcn_hubp_state *s = &hubp1->state;
1075 struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
1076
1077 hubp1_read_state_common(hubp);
1078
1079 REG_GET_8(DCHUBP_REQ_SIZE_CONFIG,
1080 CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
1081 MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
1082 META_CHUNK_SIZE, &rq_regs->rq_regs_l.meta_chunk_size,
1083 MIN_META_CHUNK_SIZE, &rq_regs->rq_regs_l.min_meta_chunk_size,
1084 DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
1085 MPTE_GROUP_SIZE, &rq_regs->rq_regs_l.mpte_group_size,
1086 SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
1087 PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
1088
1089 REG_GET_8(DCHUBP_REQ_SIZE_CONFIG_C,
1090 CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
1091 MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
1092 META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.meta_chunk_size,
1093 MIN_META_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_meta_chunk_size,
1094 DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
1095 MPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.mpte_group_size,
1096 SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
1097 PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
1098
1099 }
1100 enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch)
1101 {
1102 enum cursor_pitch hw_pitch;
1103
1104 switch (pitch) {
1105 case 64:
1106 hw_pitch = CURSOR_PITCH_64_PIXELS;
1107 break;
1108 case 128:
1109 hw_pitch = CURSOR_PITCH_128_PIXELS;
1110 break;
1111 case 256:
1112 hw_pitch = CURSOR_PITCH_256_PIXELS;
1113 break;
1114 default:
1115 DC_ERR("Invalid cursor pitch of %d. "
1116 "Only 64/128/256 is supported on DCN.\n", pitch);
1117 hw_pitch = CURSOR_PITCH_64_PIXELS;
1118 break;
1119 }
1120 return hw_pitch;
1121 }
1122
1123 static enum cursor_lines_per_chunk hubp1_get_lines_per_chunk(
1124 unsigned int cur_width,
1125 enum dc_cursor_color_format format)
1126 {
1127 enum cursor_lines_per_chunk line_per_chunk;
1128
1129 if (format == CURSOR_MODE_MONO)
1130
1131 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
1132 else if (cur_width <= 32)
1133 line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
1134 else if (cur_width <= 64)
1135 line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
1136 else if (cur_width <= 128)
1137 line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
1138 else
1139 line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
1140
1141 return line_per_chunk;
1142 }
1143
1144 void hubp1_cursor_set_attributes(
1145 struct hubp *hubp,
1146 const struct dc_cursor_attributes *attr)
1147 {
1148 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1149 enum cursor_pitch hw_pitch = hubp1_get_cursor_pitch(attr->pitch);
1150 enum cursor_lines_per_chunk lpc = hubp1_get_lines_per_chunk(
1151 attr->width, attr->color_format);
1152
1153 hubp->curs_attr = *attr;
1154
1155 REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
1156 CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
1157 REG_UPDATE(CURSOR_SURFACE_ADDRESS,
1158 CURSOR_SURFACE_ADDRESS, attr->address.low_part);
1159
1160 REG_UPDATE_2(CURSOR_SIZE,
1161 CURSOR_WIDTH, attr->width,
1162 CURSOR_HEIGHT, attr->height);
1163
1164 REG_UPDATE_3(CURSOR_CONTROL,
1165 CURSOR_MODE, attr->color_format,
1166 CURSOR_PITCH, hw_pitch,
1167 CURSOR_LINES_PER_CHUNK, lpc);
1168
1169 REG_SET_2(CURSOR_SETTINS, 0,
1170
1171 CURSOR0_DST_Y_OFFSET, 0,
1172
1173 CURSOR0_CHUNK_HDL_ADJUST, 3);
1174 }
1175
1176 void hubp1_cursor_set_position(
1177 struct hubp *hubp,
1178 const struct dc_cursor_position *pos,
1179 const struct dc_cursor_mi_param *param)
1180 {
1181 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1182 int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
1183 int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
1184 int x_hotspot = pos->x_hotspot;
1185 int y_hotspot = pos->y_hotspot;
1186 int cursor_height = (int)hubp->curs_attr.height;
1187 int cursor_width = (int)hubp->curs_attr.width;
1188 uint32_t dst_x_offset;
1189 uint32_t cur_en = pos->enable ? 1 : 0;
1190
1191 hubp->curs_pos = *pos;
1192
1193
1194
1195
1196
1197
1198
1199
1200 if (hubp->curs_attr.address.quad_part == 0)
1201 return;
1202
1203
1204 if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
1205 swap(cursor_height, cursor_width);
1206 if (param->rotation == ROTATION_ANGLE_90) {
1207 src_x_offset = pos->x - pos->y_hotspot - param->viewport.x;
1208 src_y_offset = pos->y - pos->x_hotspot - param->viewport.y;
1209 }
1210 } else if (param->rotation == ROTATION_ANGLE_180) {
1211 src_x_offset = pos->x - param->viewport.x;
1212 src_y_offset = pos->y - param->viewport.y;
1213 }
1214
1215 if (param->mirror) {
1216 x_hotspot = param->viewport.width - x_hotspot;
1217 src_x_offset = param->viewport.x + param->viewport.width - src_x_offset;
1218 }
1219
1220 dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
1221 dst_x_offset *= param->ref_clk_khz;
1222 dst_x_offset /= param->pixel_clk_khz;
1223
1224 ASSERT(param->h_scale_ratio.value);
1225
1226 if (param->h_scale_ratio.value)
1227 dst_x_offset = dc_fixpt_floor(dc_fixpt_div(
1228 dc_fixpt_from_int(dst_x_offset),
1229 param->h_scale_ratio));
1230
1231 if (src_x_offset >= (int)param->viewport.width)
1232 cur_en = 0;
1233
1234 if (src_x_offset + cursor_width <= 0)
1235 cur_en = 0;
1236
1237 if (src_y_offset >= (int)param->viewport.height)
1238 cur_en = 0;
1239
1240 if (src_y_offset + cursor_height <= 0)
1241 cur_en = 0;
1242
1243 if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
1244 hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
1245
1246 REG_UPDATE(CURSOR_CONTROL,
1247 CURSOR_ENABLE, cur_en);
1248
1249 REG_SET_2(CURSOR_POSITION, 0,
1250 CURSOR_X_POSITION, pos->x,
1251 CURSOR_Y_POSITION, pos->y);
1252
1253 REG_SET_2(CURSOR_HOT_SPOT, 0,
1254 CURSOR_HOT_SPOT_X, x_hotspot,
1255 CURSOR_HOT_SPOT_Y, y_hotspot);
1256
1257 REG_SET(CURSOR_DST_OFFSET, 0,
1258 CURSOR_DST_X_OFFSET, dst_x_offset);
1259
1260 }
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270 void hubp1_clk_cntl(struct hubp *hubp, bool enable)
1271 {
1272 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1273 uint32_t clk_enable = enable ? 1 : 0;
1274
1275 REG_UPDATE(HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, clk_enable);
1276 }
1277
1278 void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst)
1279 {
1280 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1281
1282 REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst);
1283 }
1284
1285 bool hubp1_in_blank(struct hubp *hubp)
1286 {
1287 uint32_t in_blank;
1288 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1289
1290 REG_GET(DCHUBP_CNTL, HUBP_IN_BLANK, &in_blank);
1291 return in_blank ? true : false;
1292 }
1293
1294 void hubp1_soft_reset(struct hubp *hubp, bool reset)
1295 {
1296 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1297
1298 REG_UPDATE(DCHUBP_CNTL, HUBP_DISABLE, reset ? 1 : 0);
1299 }
1300
1301
1302
1303
1304
1305
1306 void hubp1_set_flip_int(struct hubp *hubp)
1307 {
1308 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1309
1310 REG_UPDATE(DCSURF_SURFACE_FLIP_INTERRUPT,
1311 SURFACE_FLIP_INT_MASK, 1);
1312
1313 return;
1314 }
1315
1316
1317
1318
1319
1320
1321 static void hubp1_wait_pipe_read_start(struct hubp *hubp)
1322 {
1323 struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
1324
1325 REG_WAIT(HUBPRET_READ_LINE_STATUS,
1326 PIPE_READ_VBLANK, 0,
1327 1, 1000);
1328 }
1329
1330 void hubp1_init(struct hubp *hubp)
1331 {
1332
1333 }
1334 static const struct hubp_funcs dcn10_hubp_funcs = {
1335 .hubp_program_surface_flip_and_addr =
1336 hubp1_program_surface_flip_and_addr,
1337 .hubp_program_surface_config =
1338 hubp1_program_surface_config,
1339 .hubp_is_flip_pending = hubp1_is_flip_pending,
1340 .hubp_setup = hubp1_setup,
1341 .hubp_setup_interdependent = hubp1_setup_interdependent,
1342 .hubp_set_vm_system_aperture_settings = hubp1_set_vm_system_aperture_settings,
1343 .hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
1344 .set_blank = hubp1_set_blank,
1345 .dcc_control = hubp1_dcc_control,
1346 .mem_program_viewport = min_set_viewport,
1347 .set_hubp_blank_en = hubp1_set_hubp_blank_en,
1348 .set_cursor_attributes = hubp1_cursor_set_attributes,
1349 .set_cursor_position = hubp1_cursor_set_position,
1350 .hubp_disconnect = hubp1_disconnect,
1351 .hubp_clk_cntl = hubp1_clk_cntl,
1352 .hubp_vtg_sel = hubp1_vtg_sel,
1353 .hubp_read_state = hubp1_read_state,
1354 .hubp_clear_underflow = hubp1_clear_underflow,
1355 .hubp_disable_control = hubp1_disable_control,
1356 .hubp_get_underflow_status = hubp1_get_underflow_status,
1357 .hubp_init = hubp1_init,
1358
1359 .dmdata_set_attributes = NULL,
1360 .dmdata_load = NULL,
1361 .hubp_soft_reset = hubp1_soft_reset,
1362 .hubp_in_blank = hubp1_in_blank,
1363 .hubp_set_flip_int = hubp1_set_flip_int,
1364 .hubp_wait_pipe_read_start = hubp1_wait_pipe_read_start,
1365 };
1366
1367
1368
1369
1370
1371 void dcn10_hubp_construct(
1372 struct dcn10_hubp *hubp1,
1373 struct dc_context *ctx,
1374 uint32_t inst,
1375 const struct dcn_mi_registers *hubp_regs,
1376 const struct dcn_mi_shift *hubp_shift,
1377 const struct dcn_mi_mask *hubp_mask)
1378 {
1379 hubp1->base.funcs = &dcn10_hubp_funcs;
1380 hubp1->base.ctx = ctx;
1381 hubp1->hubp_regs = hubp_regs;
1382 hubp1->hubp_shift = hubp_shift;
1383 hubp1->hubp_mask = hubp_mask;
1384 hubp1->base.inst = inst;
1385 hubp1->base.opp_id = OPP_ID_INVALID;
1386 hubp1->base.mpcc_id = 0xf;
1387 }
1388
1389