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
0027 #include "dce/dce_11_0_d.h"
0028 #include "dce/dce_11_0_sh_mask.h"
0029
0030 #include "gmc/gmc_8_2_d.h"
0031 #include "gmc/gmc_8_2_sh_mask.h"
0032
0033 #include "include/logger_interface.h"
0034 #include "inc/dce_calcs.h"
0035
0036 #include "dce/dce_mem_input.h"
0037 #include "dce110_mem_input_v.h"
0038
0039 static void set_flip_control(
0040 struct dce_mem_input *mem_input110,
0041 bool immediate)
0042 {
0043 uint32_t value = 0;
0044
0045 value = dm_read_reg(
0046 mem_input110->base.ctx,
0047 mmUNP_FLIP_CONTROL);
0048
0049 set_reg_field_value(value, 1,
0050 UNP_FLIP_CONTROL,
0051 GRPH_SURFACE_UPDATE_PENDING_MODE);
0052
0053 dm_write_reg(
0054 mem_input110->base.ctx,
0055 mmUNP_FLIP_CONTROL,
0056 value);
0057 }
0058
0059
0060 static void program_pri_addr_c(
0061 struct dce_mem_input *mem_input110,
0062 PHYSICAL_ADDRESS_LOC address)
0063 {
0064 uint32_t value = 0;
0065 uint32_t temp = 0;
0066
0067 temp = address.high_part &
0068 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
0069
0070 set_reg_field_value(value, temp,
0071 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
0072 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
0073
0074 dm_write_reg(
0075 mem_input110->base.ctx,
0076 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
0077 value);
0078
0079 temp = 0;
0080 value = 0;
0081 temp = address.low_part >>
0082 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT;
0083
0084 set_reg_field_value(value, temp,
0085 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
0086 GRPH_PRIMARY_SURFACE_ADDRESS_C);
0087
0088 dm_write_reg(
0089 mem_input110->base.ctx,
0090 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
0091 value);
0092 }
0093
0094
0095 static void program_pri_addr_l(
0096 struct dce_mem_input *mem_input110,
0097 PHYSICAL_ADDRESS_LOC address)
0098 {
0099 uint32_t value = 0;
0100 uint32_t temp = 0;
0101
0102
0103 temp = address.high_part &
0104 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK;
0105
0106 set_reg_field_value(value, temp,
0107 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
0108 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L);
0109
0110 dm_write_reg(
0111 mem_input110->base.ctx,
0112 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
0113 value);
0114
0115 temp = 0;
0116 value = 0;
0117 temp = address.low_part >>
0118 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
0119
0120 set_reg_field_value(value, temp,
0121 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
0122 GRPH_PRIMARY_SURFACE_ADDRESS_L);
0123
0124 dm_write_reg(
0125 mem_input110->base.ctx,
0126 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
0127 value);
0128 }
0129
0130 static void program_addr(
0131 struct dce_mem_input *mem_input110,
0132 const struct dc_plane_address *addr)
0133 {
0134 switch (addr->type) {
0135 case PLN_ADDR_TYPE_GRAPHICS:
0136 program_pri_addr_l(
0137 mem_input110,
0138 addr->grph.addr);
0139 break;
0140 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
0141 program_pri_addr_c(
0142 mem_input110,
0143 addr->video_progressive.chroma_addr);
0144 program_pri_addr_l(
0145 mem_input110,
0146 addr->video_progressive.luma_addr);
0147 break;
0148 default:
0149
0150 BREAK_TO_DEBUGGER();
0151 }
0152 }
0153
0154 static void enable(struct dce_mem_input *mem_input110)
0155 {
0156 uint32_t value = 0;
0157
0158 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
0159 set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
0160 dm_write_reg(mem_input110->base.ctx,
0161 mmUNP_GRPH_ENABLE,
0162 value);
0163 }
0164
0165 static void program_tiling(
0166 struct dce_mem_input *mem_input110,
0167 const union dc_tiling_info *info,
0168 const enum surface_pixel_format pixel_format)
0169 {
0170 uint32_t value = 0;
0171
0172 set_reg_field_value(value, info->gfx8.num_banks,
0173 UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
0174
0175 set_reg_field_value(value, info->gfx8.bank_width,
0176 UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
0177
0178 set_reg_field_value(value, info->gfx8.bank_height,
0179 UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
0180
0181 set_reg_field_value(value, info->gfx8.tile_aspect,
0182 UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
0183
0184 set_reg_field_value(value, info->gfx8.tile_split,
0185 UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
0186
0187 set_reg_field_value(value, info->gfx8.tile_mode,
0188 UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
0189
0190 set_reg_field_value(value, info->gfx8.pipe_config,
0191 UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
0192
0193 set_reg_field_value(value, info->gfx8.array_mode,
0194 UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
0195
0196 set_reg_field_value(value, 1,
0197 UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
0198
0199 set_reg_field_value(value, 0,
0200 UNP_GRPH_CONTROL, GRPH_Z);
0201
0202 dm_write_reg(
0203 mem_input110->base.ctx,
0204 mmUNP_GRPH_CONTROL,
0205 value);
0206
0207 value = 0;
0208
0209 set_reg_field_value(value, info->gfx8.bank_width_c,
0210 UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
0211
0212 set_reg_field_value(value, info->gfx8.bank_height_c,
0213 UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
0214
0215 set_reg_field_value(value, info->gfx8.tile_aspect_c,
0216 UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
0217
0218 set_reg_field_value(value, info->gfx8.tile_split_c,
0219 UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
0220
0221 set_reg_field_value(value, info->gfx8.tile_mode_c,
0222 UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
0223
0224 dm_write_reg(
0225 mem_input110->base.ctx,
0226 mmUNP_GRPH_CONTROL_C,
0227 value);
0228 }
0229
0230 static void program_size_and_rotation(
0231 struct dce_mem_input *mem_input110,
0232 enum dc_rotation_angle rotation,
0233 const struct plane_size *plane_size)
0234 {
0235 uint32_t value = 0;
0236 struct plane_size local_size = *plane_size;
0237
0238 if (rotation == ROTATION_ANGLE_90 ||
0239 rotation == ROTATION_ANGLE_270) {
0240
0241 swap(local_size.surface_size.x,
0242 local_size.surface_size.y);
0243 swap(local_size.surface_size.width,
0244 local_size.surface_size.height);
0245 swap(local_size.chroma_size.x,
0246 local_size.chroma_size.y);
0247 swap(local_size.chroma_size.width,
0248 local_size.chroma_size.height);
0249 }
0250
0251 value = 0;
0252 set_reg_field_value(value, local_size.surface_pitch,
0253 UNP_GRPH_PITCH_L, GRPH_PITCH_L);
0254
0255 dm_write_reg(
0256 mem_input110->base.ctx,
0257 mmUNP_GRPH_PITCH_L,
0258 value);
0259
0260 value = 0;
0261 set_reg_field_value(value, local_size.chroma_pitch,
0262 UNP_GRPH_PITCH_C, GRPH_PITCH_C);
0263 dm_write_reg(
0264 mem_input110->base.ctx,
0265 mmUNP_GRPH_PITCH_C,
0266 value);
0267
0268 value = 0;
0269 set_reg_field_value(value, 0,
0270 UNP_GRPH_X_START_L, GRPH_X_START_L);
0271 dm_write_reg(
0272 mem_input110->base.ctx,
0273 mmUNP_GRPH_X_START_L,
0274 value);
0275
0276 value = 0;
0277 set_reg_field_value(value, 0,
0278 UNP_GRPH_X_START_C, GRPH_X_START_C);
0279 dm_write_reg(
0280 mem_input110->base.ctx,
0281 mmUNP_GRPH_X_START_C,
0282 value);
0283
0284 value = 0;
0285 set_reg_field_value(value, 0,
0286 UNP_GRPH_Y_START_L, GRPH_Y_START_L);
0287 dm_write_reg(
0288 mem_input110->base.ctx,
0289 mmUNP_GRPH_Y_START_L,
0290 value);
0291
0292 value = 0;
0293 set_reg_field_value(value, 0,
0294 UNP_GRPH_Y_START_C, GRPH_Y_START_C);
0295 dm_write_reg(
0296 mem_input110->base.ctx,
0297 mmUNP_GRPH_Y_START_C,
0298 value);
0299
0300 value = 0;
0301 set_reg_field_value(value, local_size.surface_size.x +
0302 local_size.surface_size.width,
0303 UNP_GRPH_X_END_L, GRPH_X_END_L);
0304 dm_write_reg(
0305 mem_input110->base.ctx,
0306 mmUNP_GRPH_X_END_L,
0307 value);
0308
0309 value = 0;
0310 set_reg_field_value(value, local_size.chroma_size.x +
0311 local_size.chroma_size.width,
0312 UNP_GRPH_X_END_C, GRPH_X_END_C);
0313 dm_write_reg(
0314 mem_input110->base.ctx,
0315 mmUNP_GRPH_X_END_C,
0316 value);
0317
0318 value = 0;
0319 set_reg_field_value(value, local_size.surface_size.y +
0320 local_size.surface_size.height,
0321 UNP_GRPH_Y_END_L, GRPH_Y_END_L);
0322 dm_write_reg(
0323 mem_input110->base.ctx,
0324 mmUNP_GRPH_Y_END_L,
0325 value);
0326
0327 value = 0;
0328 set_reg_field_value(value, local_size.chroma_size.y +
0329 local_size.chroma_size.height,
0330 UNP_GRPH_Y_END_C, GRPH_Y_END_C);
0331 dm_write_reg(
0332 mem_input110->base.ctx,
0333 mmUNP_GRPH_Y_END_C,
0334 value);
0335
0336 value = 0;
0337 switch (rotation) {
0338 case ROTATION_ANGLE_90:
0339 set_reg_field_value(value, 3,
0340 UNP_HW_ROTATION, ROTATION_ANGLE);
0341 break;
0342 case ROTATION_ANGLE_180:
0343 set_reg_field_value(value, 2,
0344 UNP_HW_ROTATION, ROTATION_ANGLE);
0345 break;
0346 case ROTATION_ANGLE_270:
0347 set_reg_field_value(value, 1,
0348 UNP_HW_ROTATION, ROTATION_ANGLE);
0349 break;
0350 default:
0351 set_reg_field_value(value, 0,
0352 UNP_HW_ROTATION, ROTATION_ANGLE);
0353 break;
0354 }
0355
0356 dm_write_reg(
0357 mem_input110->base.ctx,
0358 mmUNP_HW_ROTATION,
0359 value);
0360 }
0361
0362 static void program_pixel_format(
0363 struct dce_mem_input *mem_input110,
0364 enum surface_pixel_format format)
0365 {
0366 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
0367 uint32_t value;
0368 uint8_t grph_depth;
0369 uint8_t grph_format;
0370
0371 value = dm_read_reg(
0372 mem_input110->base.ctx,
0373 mmUNP_GRPH_CONTROL);
0374
0375 switch (format) {
0376 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
0377 grph_depth = 0;
0378 grph_format = 0;
0379 break;
0380 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
0381 grph_depth = 1;
0382 grph_format = 1;
0383 break;
0384 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
0385 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
0386 grph_depth = 2;
0387 grph_format = 0;
0388 break;
0389 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
0390 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
0391 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
0392 grph_depth = 2;
0393 grph_format = 1;
0394 break;
0395 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
0396 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
0397 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
0398 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
0399 grph_depth = 3;
0400 grph_format = 0;
0401 break;
0402 default:
0403 grph_depth = 2;
0404 grph_format = 0;
0405 break;
0406 }
0407
0408 set_reg_field_value(
0409 value,
0410 grph_depth,
0411 UNP_GRPH_CONTROL,
0412 GRPH_DEPTH);
0413 set_reg_field_value(
0414 value,
0415 grph_format,
0416 UNP_GRPH_CONTROL,
0417 GRPH_FORMAT);
0418
0419 dm_write_reg(
0420 mem_input110->base.ctx,
0421 mmUNP_GRPH_CONTROL,
0422 value);
0423
0424 value = dm_read_reg(
0425 mem_input110->base.ctx,
0426 mmUNP_GRPH_CONTROL_EXP);
0427
0428
0429 set_reg_field_value(
0430 value,
0431 0,
0432 UNP_GRPH_CONTROL_EXP,
0433 VIDEO_FORMAT);
0434 dm_write_reg(
0435 mem_input110->base.ctx,
0436 mmUNP_GRPH_CONTROL_EXP,
0437 value);
0438
0439 } else {
0440
0441 uint32_t value;
0442 uint8_t video_format;
0443
0444 value = dm_read_reg(
0445 mem_input110->base.ctx,
0446 mmUNP_GRPH_CONTROL_EXP);
0447
0448 switch (format) {
0449 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
0450 video_format = 2;
0451 break;
0452 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
0453 video_format = 3;
0454 break;
0455 default:
0456 video_format = 0;
0457 break;
0458 }
0459
0460 set_reg_field_value(
0461 value,
0462 video_format,
0463 UNP_GRPH_CONTROL_EXP,
0464 VIDEO_FORMAT);
0465
0466 dm_write_reg(
0467 mem_input110->base.ctx,
0468 mmUNP_GRPH_CONTROL_EXP,
0469 value);
0470 }
0471 }
0472
0473 static bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input)
0474 {
0475 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0476 uint32_t value;
0477
0478 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE);
0479
0480 if (get_reg_field_value(value, UNP_GRPH_UPDATE,
0481 GRPH_SURFACE_UPDATE_PENDING))
0482 return true;
0483
0484 mem_input->current_address = mem_input->request_address;
0485 return false;
0486 }
0487
0488 static bool dce_mem_input_v_program_surface_flip_and_addr(
0489 struct mem_input *mem_input,
0490 const struct dc_plane_address *address,
0491 bool flip_immediate)
0492 {
0493 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0494
0495 set_flip_control(mem_input110, flip_immediate);
0496 program_addr(mem_input110,
0497 address);
0498
0499 mem_input->request_address = *address;
0500
0501 return true;
0502 }
0503
0504
0505 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = {
0506 { 8, 64, 64, 8, 8, 1, 4, 0, 0},
0507 { 16, 64, 32, 8, 16, 1, 8, 0, 0},
0508 { 32, 32, 32, 16, 16, 1, 8, 0, 0},
0509 { 64, 8, 32, 16, 16, 1, 8, 0, 0},
0510 };
0511
0512 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = {
0513 { 8, 512, 8, 1, 0, 1, 0, 0, 0},
0514 { 16, 256, 8, 2, 0, 1, 0, 0, 0},
0515 { 32, 128, 8, 4, 0, 1, 0, 0, 0},
0516 { 64, 64, 8, 4, 0, 1, 0, 0, 0},
0517 };
0518
0519 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = {
0520 { 8, 4096, 1, 8, 0, 1, 0, 0, 0},
0521 { 16, 2048, 1, 8, 0, 1, 0, 0, 0},
0522 { 32, 1024, 1, 8, 0, 1, 0, 0, 0},
0523 { 64, 512, 1, 8, 0, 1, 0, 0, 0},
0524 };
0525
0526
0527 static const unsigned int *get_dvmm_hw_setting(
0528 union dc_tiling_info *tiling_info,
0529 enum surface_pixel_format format,
0530 bool chroma)
0531 {
0532 enum bits_per_pixel {
0533 bpp_8 = 0,
0534 bpp_16,
0535 bpp_32,
0536 bpp_64
0537 } bpp;
0538
0539 if (format >= SURFACE_PIXEL_FORMAT_INVALID)
0540 bpp = bpp_32;
0541 else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
0542 bpp = chroma ? bpp_16 : bpp_8;
0543 else
0544 bpp = bpp_8;
0545
0546 switch (tiling_info->gfx8.array_mode) {
0547 case DC_ARRAY_1D_TILED_THIN1:
0548 case DC_ARRAY_1D_TILED_THICK:
0549 case DC_ARRAY_PRT_TILED_THIN1:
0550 return dvmm_Hw_Setting_1DTiling[bpp];
0551 case DC_ARRAY_2D_TILED_THIN1:
0552 case DC_ARRAY_2D_TILED_THICK:
0553 case DC_ARRAY_2D_TILED_X_THICK:
0554 case DC_ARRAY_PRT_2D_TILED_THIN1:
0555 case DC_ARRAY_PRT_2D_TILED_THICK:
0556 return dvmm_Hw_Setting_2DTiling[bpp];
0557 case DC_ARRAY_LINEAR_GENERAL:
0558 case DC_ARRAY_LINEAR_ALLIGNED:
0559 return dvmm_Hw_Setting_Linear[bpp];
0560 default:
0561 return dvmm_Hw_Setting_2DTiling[bpp];
0562 }
0563 }
0564
0565 static void dce_mem_input_v_program_pte_vm(
0566 struct mem_input *mem_input,
0567 enum surface_pixel_format format,
0568 union dc_tiling_info *tiling_info,
0569 enum dc_rotation_angle rotation)
0570 {
0571 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0572 const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false);
0573 const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true);
0574
0575 unsigned int page_width = 0;
0576 unsigned int page_height = 0;
0577 unsigned int page_width_chroma = 0;
0578 unsigned int page_height_chroma = 0;
0579 unsigned int temp_page_width = pte[1];
0580 unsigned int temp_page_height = pte[2];
0581 unsigned int min_pte_before_flip = 0;
0582 unsigned int min_pte_before_flip_chroma = 0;
0583 uint32_t value = 0;
0584
0585 while ((temp_page_width >>= 1) != 0)
0586 page_width++;
0587 while ((temp_page_height >>= 1) != 0)
0588 page_height++;
0589
0590 temp_page_width = pte_chroma[1];
0591 temp_page_height = pte_chroma[2];
0592 while ((temp_page_width >>= 1) != 0)
0593 page_width_chroma++;
0594 while ((temp_page_height >>= 1) != 0)
0595 page_height_chroma++;
0596
0597 switch (rotation) {
0598 case ROTATION_ANGLE_90:
0599 case ROTATION_ANGLE_270:
0600 min_pte_before_flip = pte[4];
0601 min_pte_before_flip_chroma = pte_chroma[4];
0602 break;
0603 default:
0604 min_pte_before_flip = pte[3];
0605 min_pte_before_flip_chroma = pte_chroma[3];
0606 break;
0607 }
0608
0609 value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT);
0610
0611 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L);
0612 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C);
0613 dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value);
0614
0615 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL);
0616 set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH);
0617 set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT);
0618 set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP);
0619 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value);
0620
0621 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL);
0622 set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK);
0623 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING);
0624 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value);
0625
0626 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C);
0627 set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C);
0628 set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C);
0629 set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C);
0630 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value);
0631
0632 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C);
0633 set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C);
0634 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C);
0635 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value);
0636 }
0637
0638 static void dce_mem_input_v_program_surface_config(
0639 struct mem_input *mem_input,
0640 enum surface_pixel_format format,
0641 union dc_tiling_info *tiling_info,
0642 struct plane_size *plane_size,
0643 enum dc_rotation_angle rotation,
0644 struct dc_plane_dcc_param *dcc,
0645 bool horizotal_mirror)
0646 {
0647 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
0648
0649 enable(mem_input110);
0650 program_tiling(mem_input110, tiling_info, format);
0651 program_size_and_rotation(mem_input110, rotation, plane_size);
0652 program_pixel_format(mem_input110, format);
0653 }
0654
0655 static void program_urgency_watermark(
0656 const struct dc_context *ctx,
0657 const uint32_t urgency_addr,
0658 const uint32_t wm_addr,
0659 struct dce_watermarks marks_low,
0660 uint32_t total_dest_line_time_ns)
0661 {
0662
0663 uint32_t urgency_cntl = 0;
0664 uint32_t wm_mask_cntl = 0;
0665
0666
0667 wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0668 set_reg_field_value(wm_mask_cntl,
0669 1,
0670 DPGV0_WATERMARK_MASK_CONTROL,
0671 URGENCY_WATERMARK_MASK);
0672 dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0673
0674 urgency_cntl = dm_read_reg(ctx, urgency_addr);
0675
0676 set_reg_field_value(
0677 urgency_cntl,
0678 marks_low.a_mark,
0679 DPGV0_PIPE_URGENCY_CONTROL,
0680 URGENCY_LOW_WATERMARK);
0681
0682 set_reg_field_value(
0683 urgency_cntl,
0684 total_dest_line_time_ns,
0685 DPGV0_PIPE_URGENCY_CONTROL,
0686 URGENCY_HIGH_WATERMARK);
0687 dm_write_reg(ctx, urgency_addr, urgency_cntl);
0688
0689
0690 wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0691 set_reg_field_value(wm_mask_cntl,
0692 2,
0693 DPGV0_WATERMARK_MASK_CONTROL,
0694 URGENCY_WATERMARK_MASK);
0695 dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0696
0697 urgency_cntl = dm_read_reg(ctx, urgency_addr);
0698
0699 set_reg_field_value(urgency_cntl,
0700 marks_low.b_mark,
0701 DPGV0_PIPE_URGENCY_CONTROL,
0702 URGENCY_LOW_WATERMARK);
0703
0704 set_reg_field_value(urgency_cntl,
0705 total_dest_line_time_ns,
0706 DPGV0_PIPE_URGENCY_CONTROL,
0707 URGENCY_HIGH_WATERMARK);
0708
0709 dm_write_reg(ctx, urgency_addr, urgency_cntl);
0710 }
0711
0712 static void program_urgency_watermark_l(
0713 const struct dc_context *ctx,
0714 struct dce_watermarks marks_low,
0715 uint32_t total_dest_line_time_ns)
0716 {
0717 program_urgency_watermark(
0718 ctx,
0719 mmDPGV0_PIPE_URGENCY_CONTROL,
0720 mmDPGV0_WATERMARK_MASK_CONTROL,
0721 marks_low,
0722 total_dest_line_time_ns);
0723 }
0724
0725 static void program_urgency_watermark_c(
0726 const struct dc_context *ctx,
0727 struct dce_watermarks marks_low,
0728 uint32_t total_dest_line_time_ns)
0729 {
0730 program_urgency_watermark(
0731 ctx,
0732 mmDPGV1_PIPE_URGENCY_CONTROL,
0733 mmDPGV1_WATERMARK_MASK_CONTROL,
0734 marks_low,
0735 total_dest_line_time_ns);
0736 }
0737
0738 static void program_stutter_watermark(
0739 const struct dc_context *ctx,
0740 const uint32_t stutter_addr,
0741 const uint32_t wm_addr,
0742 struct dce_watermarks marks)
0743 {
0744
0745 uint32_t stutter_cntl = 0;
0746 uint32_t wm_mask_cntl = 0;
0747
0748
0749
0750 wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0751 set_reg_field_value(wm_mask_cntl,
0752 1,
0753 DPGV0_WATERMARK_MASK_CONTROL,
0754 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
0755 dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0756
0757 stutter_cntl = dm_read_reg(ctx, stutter_addr);
0758
0759 if (ctx->dc->debug.disable_stutter) {
0760 set_reg_field_value(stutter_cntl,
0761 0,
0762 DPGV0_PIPE_STUTTER_CONTROL,
0763 STUTTER_ENABLE);
0764 } else {
0765 set_reg_field_value(stutter_cntl,
0766 1,
0767 DPGV0_PIPE_STUTTER_CONTROL,
0768 STUTTER_ENABLE);
0769 }
0770
0771 set_reg_field_value(stutter_cntl,
0772 1,
0773 DPGV0_PIPE_STUTTER_CONTROL,
0774 STUTTER_IGNORE_FBC);
0775
0776
0777 set_reg_field_value(stutter_cntl,
0778 marks.a_mark,
0779 DPGV0_PIPE_STUTTER_CONTROL,
0780 STUTTER_EXIT_SELF_REFRESH_WATERMARK);
0781 dm_write_reg(ctx, stutter_addr, stutter_cntl);
0782
0783
0784 wm_mask_cntl = dm_read_reg(ctx, wm_addr);
0785 set_reg_field_value(wm_mask_cntl,
0786 2,
0787 DPGV0_WATERMARK_MASK_CONTROL,
0788 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
0789 dm_write_reg(ctx, wm_addr, wm_mask_cntl);
0790
0791 stutter_cntl = dm_read_reg(ctx, stutter_addr);
0792
0793 set_reg_field_value(stutter_cntl,
0794 marks.b_mark,
0795 DPGV0_PIPE_STUTTER_CONTROL,
0796 STUTTER_EXIT_SELF_REFRESH_WATERMARK);
0797 dm_write_reg(ctx, stutter_addr, stutter_cntl);
0798 }
0799
0800 static void program_stutter_watermark_l(
0801 const struct dc_context *ctx,
0802 struct dce_watermarks marks)
0803 {
0804 program_stutter_watermark(ctx,
0805 mmDPGV0_PIPE_STUTTER_CONTROL,
0806 mmDPGV0_WATERMARK_MASK_CONTROL,
0807 marks);
0808 }
0809
0810 static void program_stutter_watermark_c(
0811 const struct dc_context *ctx,
0812 struct dce_watermarks marks)
0813 {
0814 program_stutter_watermark(ctx,
0815 mmDPGV1_PIPE_STUTTER_CONTROL,
0816 mmDPGV1_WATERMARK_MASK_CONTROL,
0817 marks);
0818 }
0819
0820 static void program_nbp_watermark(
0821 const struct dc_context *ctx,
0822 const uint32_t wm_mask_ctrl_addr,
0823 const uint32_t nbp_pstate_ctrl_addr,
0824 struct dce_watermarks marks)
0825 {
0826 uint32_t value;
0827
0828
0829
0830 value = dm_read_reg(ctx, wm_mask_ctrl_addr);
0831
0832 set_reg_field_value(
0833 value,
0834 1,
0835 DPGV0_WATERMARK_MASK_CONTROL,
0836 NB_PSTATE_CHANGE_WATERMARK_MASK);
0837 dm_write_reg(ctx, wm_mask_ctrl_addr, value);
0838
0839 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0840
0841 set_reg_field_value(
0842 value,
0843 1,
0844 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0845 NB_PSTATE_CHANGE_ENABLE);
0846 set_reg_field_value(
0847 value,
0848 1,
0849 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0850 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
0851 set_reg_field_value(
0852 value,
0853 1,
0854 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0855 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
0856 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0857
0858
0859 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0860 set_reg_field_value(
0861 value,
0862 marks.a_mark,
0863 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0864 NB_PSTATE_CHANGE_WATERMARK);
0865 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0866
0867
0868 value = dm_read_reg(ctx, wm_mask_ctrl_addr);
0869 set_reg_field_value(
0870 value,
0871 2,
0872 DPGV0_WATERMARK_MASK_CONTROL,
0873 NB_PSTATE_CHANGE_WATERMARK_MASK);
0874 dm_write_reg(ctx, wm_mask_ctrl_addr, value);
0875
0876 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0877 set_reg_field_value(
0878 value,
0879 1,
0880 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0881 NB_PSTATE_CHANGE_ENABLE);
0882 set_reg_field_value(
0883 value,
0884 1,
0885 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0886 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
0887 set_reg_field_value(
0888 value,
0889 1,
0890 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0891 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
0892 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0893
0894
0895 value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
0896 set_reg_field_value(
0897 value,
0898 marks.b_mark,
0899 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0900 NB_PSTATE_CHANGE_WATERMARK);
0901 dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
0902 }
0903
0904 static void program_nbp_watermark_l(
0905 const struct dc_context *ctx,
0906 struct dce_watermarks marks)
0907 {
0908 program_nbp_watermark(ctx,
0909 mmDPGV0_WATERMARK_MASK_CONTROL,
0910 mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
0911 marks);
0912 }
0913
0914 static void program_nbp_watermark_c(
0915 const struct dc_context *ctx,
0916 struct dce_watermarks marks)
0917 {
0918 program_nbp_watermark(ctx,
0919 mmDPGV1_WATERMARK_MASK_CONTROL,
0920 mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL,
0921 marks);
0922 }
0923
0924 static void dce_mem_input_v_program_display_marks(
0925 struct mem_input *mem_input,
0926 struct dce_watermarks nbp,
0927 struct dce_watermarks stutter,
0928 struct dce_watermarks stutter_enter,
0929 struct dce_watermarks urgent,
0930 uint32_t total_dest_line_time_ns)
0931 {
0932 program_urgency_watermark_l(
0933 mem_input->ctx,
0934 urgent,
0935 total_dest_line_time_ns);
0936
0937 program_nbp_watermark_l(
0938 mem_input->ctx,
0939 nbp);
0940
0941 program_stutter_watermark_l(
0942 mem_input->ctx,
0943 stutter);
0944
0945 }
0946
0947 static void dce_mem_input_program_chroma_display_marks(
0948 struct mem_input *mem_input,
0949 struct dce_watermarks nbp,
0950 struct dce_watermarks stutter,
0951 struct dce_watermarks urgent,
0952 uint32_t total_dest_line_time_ns)
0953 {
0954 program_urgency_watermark_c(
0955 mem_input->ctx,
0956 urgent,
0957 total_dest_line_time_ns);
0958
0959 program_nbp_watermark_c(
0960 mem_input->ctx,
0961 nbp);
0962
0963 program_stutter_watermark_c(
0964 mem_input->ctx,
0965 stutter);
0966 }
0967
0968 static void dce110_allocate_mem_input_v(
0969 struct mem_input *mi,
0970 uint32_t h_total,
0971 uint32_t v_total,
0972 uint32_t pix_clk_khz,
0973 uint32_t total_stream_num)
0974 {
0975 uint32_t addr;
0976 uint32_t value;
0977 uint32_t pix_dur;
0978 if (pix_clk_khz != 0) {
0979 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1;
0980 value = dm_read_reg(mi->ctx, addr);
0981 pix_dur = 1000000000ULL / pix_clk_khz;
0982 set_reg_field_value(
0983 value,
0984 pix_dur,
0985 DPGV0_PIPE_ARBITRATION_CONTROL1,
0986 PIXEL_DURATION);
0987 dm_write_reg(mi->ctx, addr, value);
0988
0989 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1;
0990 value = dm_read_reg(mi->ctx, addr);
0991 pix_dur = 1000000000ULL / pix_clk_khz;
0992 set_reg_field_value(
0993 value,
0994 pix_dur,
0995 DPGV1_PIPE_ARBITRATION_CONTROL1,
0996 PIXEL_DURATION);
0997 dm_write_reg(mi->ctx, addr, value);
0998
0999 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2;
1000 value = 0x4000800;
1001 dm_write_reg(mi->ctx, addr, value);
1002
1003 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2;
1004 value = 0x4000800;
1005 dm_write_reg(mi->ctx, addr, value);
1006 }
1007
1008 }
1009
1010 static void dce110_free_mem_input_v(
1011 struct mem_input *mi,
1012 uint32_t total_stream_num)
1013 {
1014 }
1015
1016 static const struct mem_input_funcs dce110_mem_input_v_funcs = {
1017 .mem_input_program_display_marks =
1018 dce_mem_input_v_program_display_marks,
1019 .mem_input_program_chroma_display_marks =
1020 dce_mem_input_program_chroma_display_marks,
1021 .allocate_mem_input = dce110_allocate_mem_input_v,
1022 .free_mem_input = dce110_free_mem_input_v,
1023 .mem_input_program_surface_flip_and_addr =
1024 dce_mem_input_v_program_surface_flip_and_addr,
1025 .mem_input_program_pte_vm =
1026 dce_mem_input_v_program_pte_vm,
1027 .mem_input_program_surface_config =
1028 dce_mem_input_v_program_surface_config,
1029 .mem_input_is_flip_pending =
1030 dce_mem_input_v_is_surface_pending
1031 };
1032
1033
1034
1035
1036 void dce110_mem_input_v_construct(
1037 struct dce_mem_input *dce_mi,
1038 struct dc_context *ctx)
1039 {
1040 dce_mi->base.funcs = &dce110_mem_input_v_funcs;
1041 dce_mi->base.ctx = ctx;
1042 }
1043