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
0026 #include "dm_services.h"
0027
0028 #include "dce/dce_11_2_d.h"
0029 #include "dce/dce_11_2_sh_mask.h"
0030 #include "gmc/gmc_8_1_sh_mask.h"
0031 #include "gmc/gmc_8_1_d.h"
0032
0033 #include "include/logger_interface.h"
0034
0035 #include "dce112_compressor.h"
0036 #define DC_LOGGER \
0037 cp110->base.ctx->logger
0038 #define DCP_REG(reg)\
0039 (reg + cp110->offsets.dcp_offset)
0040 #define DMIF_REG(reg)\
0041 (reg + cp110->offsets.dmif_offset)
0042
0043 static const struct dce112_compressor_reg_offsets reg_offsets[] = {
0044 {
0045 .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
0046 .dmif_offset =
0047 (mmDMIF_PG0_DPG_PIPE_DPM_CONTROL
0048 - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
0049 },
0050 {
0051 .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
0052 .dmif_offset =
0053 (mmDMIF_PG1_DPG_PIPE_DPM_CONTROL
0054 - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
0055 },
0056 {
0057 .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
0058 .dmif_offset =
0059 (mmDMIF_PG2_DPG_PIPE_DPM_CONTROL
0060 - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
0061 }
0062 };
0063
0064 static const uint32_t dce11_one_lpt_channel_max_resolution = 2560 * 1600;
0065
0066 enum fbc_idle_force {
0067
0068 FBC_IDLE_FORCE_DISPLAY_REGISTER_UPDATE = 0x00000001,
0069
0070
0071 FBC_IDLE_FORCE_GRPH_COMP_EN = 0x00000002,
0072
0073 FBC_IDLE_FORCE_SRC_SEL_CHANGE = 0x00000004,
0074
0075 FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE = 0x00000008,
0076
0077 FBC_IDLE_FORCE_ALPHA_COMP_EN = 0x00000010,
0078
0079 FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN = 0x00000020,
0080
0081 FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF = 0x00000040,
0082
0083
0084 FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION0 = 0x01000000,
0085
0086 FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION1 = 0x02000000,
0087
0088 FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION2 = 0x04000000,
0089
0090 FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION3 = 0x08000000,
0091
0092
0093 FBC_IDLE_FORCE_MEMORY_WRITE_OTHER_THAN_MCIF = 0x10000000,
0094
0095 FBC_IDLE_FORCE_CG_STATIC_SCREEN_IS_INACTIVE = 0x20000000,
0096 };
0097
0098 static uint32_t lpt_size_alignment(struct dce112_compressor *cp110)
0099 {
0100
0101 return cp110->base.raw_size * cp110->base.banks_num *
0102 cp110->base.dram_channels_num;
0103 }
0104
0105 static uint32_t lpt_memory_control_config(struct dce112_compressor *cp110,
0106 uint32_t lpt_control)
0107 {
0108
0109 if (cp110->base.options.bits.LPT_MC_CONFIG == 1) {
0110
0111
0112
0113
0114
0115
0116
0117 switch (cp110->base.dram_channels_num) {
0118 case 2:
0119 set_reg_field_value(
0120 lpt_control,
0121 1,
0122 LOW_POWER_TILING_CONTROL,
0123 LOW_POWER_TILING_NUM_PIPES);
0124 break;
0125 case 1:
0126 set_reg_field_value(
0127 lpt_control,
0128 0,
0129 LOW_POWER_TILING_CONTROL,
0130 LOW_POWER_TILING_NUM_PIPES);
0131 break;
0132 default:
0133 DC_LOG_WARNING(
0134 "%s: Invalid LPT NUM_PIPES!!!",
0135 __func__);
0136 break;
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 switch (cp110->base.banks_num) {
0149 case 16:
0150 set_reg_field_value(
0151 lpt_control,
0152 3,
0153 LOW_POWER_TILING_CONTROL,
0154 LOW_POWER_TILING_NUM_BANKS);
0155 break;
0156 case 8:
0157 set_reg_field_value(
0158 lpt_control,
0159 2,
0160 LOW_POWER_TILING_CONTROL,
0161 LOW_POWER_TILING_NUM_BANKS);
0162 break;
0163 case 4:
0164 set_reg_field_value(
0165 lpt_control,
0166 1,
0167 LOW_POWER_TILING_CONTROL,
0168 LOW_POWER_TILING_NUM_BANKS);
0169 break;
0170 case 2:
0171 set_reg_field_value(
0172 lpt_control,
0173 0,
0174 LOW_POWER_TILING_CONTROL,
0175 LOW_POWER_TILING_NUM_BANKS);
0176 break;
0177 default:
0178 DC_LOG_WARNING(
0179 "%s: Invalid LPT NUM_BANKS!!!",
0180 __func__);
0181 break;
0182 }
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 switch (cp110->base.channel_interleave_size) {
0196 case 256:
0197 set_reg_field_value(
0198 lpt_control,
0199 0,
0200 LOW_POWER_TILING_CONTROL,
0201 LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
0202 break;
0203 case 512:
0204 set_reg_field_value(
0205 lpt_control,
0206 1,
0207 LOW_POWER_TILING_CONTROL,
0208 LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
0209 break;
0210 default:
0211 DC_LOG_WARNING(
0212 "%s: Invalid LPT INTERLEAVE_SIZE!!!",
0213 __func__);
0214 break;
0215 }
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 switch (cp110->base.raw_size) {
0232 case 4096:
0233 set_reg_field_value(
0234 lpt_control,
0235 2,
0236 LOW_POWER_TILING_CONTROL,
0237 LOW_POWER_TILING_ROW_SIZE);
0238 break;
0239 case 2048:
0240 set_reg_field_value(
0241 lpt_control,
0242 1,
0243 LOW_POWER_TILING_CONTROL,
0244 LOW_POWER_TILING_ROW_SIZE);
0245 break;
0246 case 1024:
0247 set_reg_field_value(
0248 lpt_control,
0249 0,
0250 LOW_POWER_TILING_CONTROL,
0251 LOW_POWER_TILING_ROW_SIZE);
0252 break;
0253 default:
0254 DC_LOG_WARNING(
0255 "%s: Invalid LPT ROW_SIZE!!!",
0256 __func__);
0257 break;
0258 }
0259 } else {
0260 DC_LOG_WARNING(
0261 "%s: LPT MC Configuration is not provided",
0262 __func__);
0263 }
0264
0265 return lpt_control;
0266 }
0267
0268 static bool is_source_bigger_than_epanel_size(
0269 struct dce112_compressor *cp110,
0270 uint32_t source_view_width,
0271 uint32_t source_view_height)
0272 {
0273 if (cp110->base.embedded_panel_h_size != 0 &&
0274 cp110->base.embedded_panel_v_size != 0 &&
0275 ((source_view_width * source_view_height) >
0276 (cp110->base.embedded_panel_h_size *
0277 cp110->base.embedded_panel_v_size)))
0278 return true;
0279
0280 return false;
0281 }
0282
0283 static uint32_t align_to_chunks_number_per_line(
0284 struct dce112_compressor *cp110,
0285 uint32_t pixels)
0286 {
0287 return 256 * ((pixels + 255) / 256);
0288 }
0289
0290 static void wait_for_fbc_state_changed(
0291 struct dce112_compressor *cp110,
0292 bool enabled)
0293 {
0294 uint8_t counter = 0;
0295 uint32_t addr = mmFBC_STATUS;
0296 uint32_t value;
0297
0298 while (counter < 10) {
0299 value = dm_read_reg(cp110->base.ctx, addr);
0300 if (get_reg_field_value(
0301 value,
0302 FBC_STATUS,
0303 FBC_ENABLE_STATUS) == enabled)
0304 break;
0305 udelay(10);
0306 counter++;
0307 }
0308
0309 if (counter == 10) {
0310 DC_LOG_WARNING(
0311 "%s: wait counter exceeded, changes to HW not applied",
0312 __func__);
0313 }
0314 }
0315
0316 void dce112_compressor_power_up_fbc(struct compressor *compressor)
0317 {
0318 uint32_t value;
0319 uint32_t addr;
0320
0321 addr = mmFBC_CNTL;
0322 value = dm_read_reg(compressor->ctx, addr);
0323 set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
0324 set_reg_field_value(value, 1, FBC_CNTL, FBC_EN);
0325 set_reg_field_value(value, 2, FBC_CNTL, FBC_COHERENCY_MODE);
0326 if (compressor->options.bits.CLK_GATING_DISABLED == 1) {
0327
0328 set_reg_field_value(
0329 value,
0330 0,
0331 FBC_CNTL,
0332 FBC_COMP_CLK_GATE_EN);
0333 }
0334 dm_write_reg(compressor->ctx, addr, value);
0335
0336 addr = mmFBC_COMP_MODE;
0337 value = dm_read_reg(compressor->ctx, addr);
0338 set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_RLE_EN);
0339 set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_DPCM4_RGB_EN);
0340 set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_IND_EN);
0341 dm_write_reg(compressor->ctx, addr, value);
0342
0343 addr = mmFBC_COMP_CNTL;
0344 value = dm_read_reg(compressor->ctx, addr);
0345 set_reg_field_value(value, 1, FBC_COMP_CNTL, FBC_DEPTH_RGB08_EN);
0346 dm_write_reg(compressor->ctx, addr, value);
0347
0348
0349
0350
0351 set_reg_field_value(value, 0xF, FBC_COMP_CNTL, FBC_MIN_COMPRESSION);
0352 dm_write_reg(compressor->ctx, addr, value);
0353 compressor->min_compress_ratio = FBC_COMPRESS_RATIO_1TO1;
0354
0355 value = 0;
0356 dm_write_reg(compressor->ctx, mmFBC_IND_LUT0, value);
0357
0358 value = 0xFFFFFF;
0359 dm_write_reg(compressor->ctx, mmFBC_IND_LUT1, value);
0360 }
0361
0362 void dce112_compressor_enable_fbc(
0363 struct compressor *compressor,
0364 uint32_t paths_num,
0365 struct compr_addr_and_pitch_params *params)
0366 {
0367 struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
0368
0369 if (compressor->options.bits.FBC_SUPPORT &&
0370 (compressor->options.bits.DUMMY_BACKEND == 0) &&
0371 (!dce112_compressor_is_fbc_enabled_in_hw(compressor, NULL)) &&
0372 (!is_source_bigger_than_epanel_size(
0373 cp110,
0374 params->source_view_width,
0375 params->source_view_height))) {
0376
0377 uint32_t addr;
0378 uint32_t value;
0379
0380
0381
0382
0383 if (compressor->options.bits.LPT_SUPPORT && (paths_num < 2) &&
0384 (params->source_view_width *
0385 params->source_view_height <=
0386 dce11_one_lpt_channel_max_resolution)) {
0387 dce112_compressor_enable_lpt(compressor);
0388 }
0389
0390 addr = mmFBC_CNTL;
0391 value = dm_read_reg(compressor->ctx, addr);
0392 set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN);
0393 set_reg_field_value(
0394 value,
0395 params->inst,
0396 FBC_CNTL, FBC_SRC_SEL);
0397 dm_write_reg(compressor->ctx, addr, value);
0398
0399
0400 compressor->is_enabled = true;
0401 compressor->attached_inst = params->inst;
0402 cp110->offsets = reg_offsets[params->inst];
0403
0404
0405 set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
0406 dm_write_reg(compressor->ctx, addr, value);
0407 set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN);
0408 dm_write_reg(compressor->ctx, addr, value);
0409
0410 wait_for_fbc_state_changed(cp110, true);
0411 }
0412 }
0413
0414 void dce112_compressor_disable_fbc(struct compressor *compressor)
0415 {
0416 struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
0417
0418 if (compressor->options.bits.FBC_SUPPORT &&
0419 dce112_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
0420 uint32_t reg_data;
0421
0422 reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL);
0423 set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
0424 dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data);
0425
0426
0427 compressor->attached_inst = 0;
0428 compressor->is_enabled = false;
0429
0430
0431
0432 if (compressor->options.bits.LPT_SUPPORT)
0433 dce112_compressor_disable_lpt(compressor);
0434
0435 wait_for_fbc_state_changed(cp110, false);
0436 }
0437 }
0438
0439 bool dce112_compressor_is_fbc_enabled_in_hw(
0440 struct compressor *compressor,
0441 uint32_t *inst)
0442 {
0443
0444 uint32_t value;
0445
0446 value = dm_read_reg(compressor->ctx, mmFBC_STATUS);
0447 if (get_reg_field_value(value, FBC_STATUS, FBC_ENABLE_STATUS)) {
0448 if (inst != NULL)
0449 *inst = compressor->attached_inst;
0450 return true;
0451 }
0452
0453 value = dm_read_reg(compressor->ctx, mmFBC_MISC);
0454 if (get_reg_field_value(value, FBC_MISC, FBC_STOP_ON_HFLIP_EVENT)) {
0455 value = dm_read_reg(compressor->ctx, mmFBC_CNTL);
0456
0457 if (get_reg_field_value(value, FBC_CNTL, FBC_GRPH_COMP_EN)) {
0458 if (inst != NULL)
0459 *inst =
0460 compressor->attached_inst;
0461 return true;
0462 }
0463 }
0464 return false;
0465 }
0466
0467 bool dce112_compressor_is_lpt_enabled_in_hw(struct compressor *compressor)
0468 {
0469
0470 uint32_t value = dm_read_reg(compressor->ctx,
0471 mmLOW_POWER_TILING_CONTROL);
0472
0473 return get_reg_field_value(
0474 value,
0475 LOW_POWER_TILING_CONTROL,
0476 LOW_POWER_TILING_ENABLE);
0477 }
0478
0479 void dce112_compressor_program_compressed_surface_address_and_pitch(
0480 struct compressor *compressor,
0481 struct compr_addr_and_pitch_params *params)
0482 {
0483 struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
0484 uint32_t value = 0;
0485 uint32_t fbc_pitch = 0;
0486 uint32_t compressed_surf_address_low_part =
0487 compressor->compr_surface_address.addr.low_part;
0488
0489
0490 dm_write_reg(
0491 compressor->ctx,
0492 DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
0493 0);
0494 dm_write_reg(compressor->ctx,
0495 DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS), 0);
0496
0497 if (compressor->options.bits.LPT_SUPPORT) {
0498 uint32_t lpt_alignment = lpt_size_alignment(cp110);
0499
0500 if (lpt_alignment != 0) {
0501 compressed_surf_address_low_part =
0502 ((compressed_surf_address_low_part
0503 + (lpt_alignment - 1)) / lpt_alignment)
0504 * lpt_alignment;
0505 }
0506 }
0507
0508
0509 dm_write_reg(compressor->ctx,
0510 DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
0511 compressor->compr_surface_address.addr.high_part);
0512 dm_write_reg(compressor->ctx,
0513 DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS),
0514 compressed_surf_address_low_part);
0515
0516 fbc_pitch = align_to_chunks_number_per_line(
0517 cp110,
0518 params->source_view_width);
0519
0520 if (compressor->min_compress_ratio == FBC_COMPRESS_RATIO_1TO1)
0521 fbc_pitch = fbc_pitch / 8;
0522 else
0523 DC_LOG_WARNING(
0524 "%s: Unexpected DCE11 compression ratio",
0525 __func__);
0526
0527
0528 dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), 0);
0529
0530
0531 set_reg_field_value(
0532 value,
0533 fbc_pitch,
0534 GRPH_COMPRESS_PITCH,
0535 GRPH_COMPRESS_PITCH);
0536 dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), value);
0537
0538 }
0539
0540 void dce112_compressor_disable_lpt(struct compressor *compressor)
0541 {
0542 struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
0543 uint32_t value;
0544 uint32_t addr;
0545 uint32_t inx;
0546
0547
0548 for (inx = 0; inx < 3; inx++) {
0549 value =
0550 dm_read_reg(
0551 compressor->ctx,
0552 DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH));
0553 set_reg_field_value(
0554 value,
0555 0,
0556 DPG_PIPE_STUTTER_CONTROL_NONLPTCH,
0557 STUTTER_ENABLE_NONLPTCH);
0558 dm_write_reg(
0559 compressor->ctx,
0560 DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH),
0561 value);
0562 }
0563
0564 addr = mmDPGV0_PIPE_STUTTER_CONTROL_NONLPTCH;
0565 value = dm_read_reg(compressor->ctx, addr);
0566 set_reg_field_value(
0567 value,
0568 0,
0569 DPGV0_PIPE_STUTTER_CONTROL_NONLPTCH,
0570 STUTTER_ENABLE_NONLPTCH);
0571 dm_write_reg(compressor->ctx, addr, value);
0572
0573
0574 addr = mmLOW_POWER_TILING_CONTROL;
0575 value = dm_read_reg(compressor->ctx, addr);
0576 set_reg_field_value(
0577 value,
0578 0,
0579 LOW_POWER_TILING_CONTROL,
0580 LOW_POWER_TILING_ENABLE);
0581 dm_write_reg(compressor->ctx, addr, value);
0582
0583
0584 addr = mmGMCON_LPT_TARGET;
0585 value = dm_read_reg(compressor->ctx, addr);
0586 set_reg_field_value(
0587 value,
0588 0xFFFFFFFF,
0589 GMCON_LPT_TARGET,
0590 STCTRL_LPT_TARGET);
0591 dm_write_reg(compressor->ctx, mmGMCON_LPT_TARGET, value);
0592 }
0593
0594 void dce112_compressor_enable_lpt(struct compressor *compressor)
0595 {
0596 struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
0597 uint32_t value;
0598 uint32_t addr;
0599 uint32_t value_control;
0600 uint32_t channels;
0601
0602
0603 value = dm_read_reg(compressor->ctx,
0604 DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH));
0605 set_reg_field_value(
0606 value,
0607 1,
0608 DPG_PIPE_STUTTER_CONTROL_NONLPTCH,
0609 STUTTER_ENABLE_NONLPTCH);
0610 dm_write_reg(compressor->ctx,
0611 DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH), value);
0612
0613
0614 addr = mmDPGV0_PIPE_STUTTER_CONTROL_NONLPTCH;
0615 value = dm_read_reg(compressor->ctx, addr);
0616 set_reg_field_value(
0617 value,
0618 1,
0619 DPGV0_PIPE_STUTTER_CONTROL_NONLPTCH,
0620 STUTTER_ENABLE_NONLPTCH);
0621 dm_write_reg(compressor->ctx, addr, value);
0622
0623
0624
0625
0626 addr = mmLOW_POWER_TILING_CONTROL;
0627 value_control = dm_read_reg(compressor->ctx, addr);
0628 channels = get_reg_field_value(value_control,
0629 LOW_POWER_TILING_CONTROL,
0630 LOW_POWER_TILING_MODE);
0631
0632 addr = mmGMCON_LPT_TARGET;
0633 value = dm_read_reg(compressor->ctx, addr);
0634 set_reg_field_value(
0635 value,
0636 channels + 1,
0637
0638 GMCON_LPT_TARGET,
0639 STCTRL_LPT_TARGET);
0640 dm_write_reg(compressor->ctx, addr, value);
0641
0642
0643 addr = mmLOW_POWER_TILING_CONTROL;
0644 value = dm_read_reg(compressor->ctx, addr);
0645 set_reg_field_value(
0646 value,
0647 1,
0648 LOW_POWER_TILING_CONTROL,
0649 LOW_POWER_TILING_ENABLE);
0650 dm_write_reg(compressor->ctx, addr, value);
0651 }
0652
0653 void dce112_compressor_program_lpt_control(
0654 struct compressor *compressor,
0655 struct compr_addr_and_pitch_params *params)
0656 {
0657 struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
0658 uint32_t rows_per_channel;
0659 uint32_t lpt_alignment;
0660 uint32_t source_view_width;
0661 uint32_t source_view_height;
0662 uint32_t lpt_control = 0;
0663
0664 if (!compressor->options.bits.LPT_SUPPORT)
0665 return;
0666
0667 lpt_control = dm_read_reg(compressor->ctx,
0668 mmLOW_POWER_TILING_CONTROL);
0669
0670
0671
0672
0673
0674
0675 switch (compressor->lpt_channels_num) {
0676
0677
0678 case 1:
0679
0680 set_reg_field_value(
0681 lpt_control,
0682 0,
0683 LOW_POWER_TILING_CONTROL,
0684 LOW_POWER_TILING_MODE);
0685 break;
0686 default:
0687 DC_LOG_WARNING(
0688 "%s: Invalid selected DRAM channels for LPT!!!",
0689 __func__);
0690 break;
0691 }
0692
0693 lpt_control = lpt_memory_control_config(cp110, lpt_control);
0694
0695
0696
0697
0698
0699
0700 rows_per_channel = 0;
0701 lpt_alignment = lpt_size_alignment(cp110);
0702 source_view_width =
0703 align_to_chunks_number_per_line(
0704 cp110,
0705 params->source_view_width);
0706 source_view_height = (params->source_view_height + 1) & (~0x1);
0707
0708 if (lpt_alignment != 0) {
0709 rows_per_channel = source_view_width * source_view_height * 4;
0710 rows_per_channel =
0711 (rows_per_channel % lpt_alignment) ?
0712 (rows_per_channel / lpt_alignment + 1) :
0713 rows_per_channel / lpt_alignment;
0714 }
0715
0716 set_reg_field_value(
0717 lpt_control,
0718 rows_per_channel,
0719 LOW_POWER_TILING_CONTROL,
0720 LOW_POWER_TILING_ROWS_PER_CHAN);
0721
0722 dm_write_reg(compressor->ctx,
0723 mmLOW_POWER_TILING_CONTROL, lpt_control);
0724 }
0725
0726
0727
0728
0729
0730 void dce112_compressor_set_fbc_invalidation_triggers(
0731 struct compressor *compressor,
0732 uint32_t fbc_trigger)
0733 {
0734
0735
0736
0737 uint32_t addr = mmFBC_CLIENT_REGION_MASK;
0738 uint32_t value = dm_read_reg(compressor->ctx, addr);
0739
0740 set_reg_field_value(
0741 value,
0742 0,
0743 FBC_CLIENT_REGION_MASK,
0744 FBC_MEMORY_REGION_MASK);
0745 dm_write_reg(compressor->ctx, addr, value);
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771 addr = mmFBC_IDLE_FORCE_CLEAR_MASK;
0772 value = dm_read_reg(compressor->ctx, addr);
0773 set_reg_field_value(
0774 value,
0775 fbc_trigger |
0776 FBC_IDLE_FORCE_GRPH_COMP_EN |
0777 FBC_IDLE_FORCE_SRC_SEL_CHANGE |
0778 FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE |
0779 FBC_IDLE_FORCE_ALPHA_COMP_EN |
0780 FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN |
0781 FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF,
0782 FBC_IDLE_FORCE_CLEAR_MASK,
0783 FBC_IDLE_FORCE_CLEAR_MASK);
0784 dm_write_reg(compressor->ctx, addr, value);
0785 }
0786
0787 void dce112_compressor_construct(struct dce112_compressor *compressor,
0788 struct dc_context *ctx)
0789 {
0790 struct dc_bios *bp = ctx->dc_bios;
0791 struct embedded_panel_info panel_info;
0792
0793 compressor->base.options.raw = 0;
0794 compressor->base.options.bits.FBC_SUPPORT = true;
0795 compressor->base.options.bits.LPT_SUPPORT = true;
0796
0797 compressor->base.lpt_channels_num = 1;
0798 compressor->base.options.bits.DUMMY_BACKEND = false;
0799
0800
0801
0802 if (compressor->base.memory_bus_width == 64)
0803 compressor->base.options.bits.LPT_SUPPORT = false;
0804
0805 compressor->base.options.bits.CLK_GATING_DISABLED = false;
0806
0807 compressor->base.ctx = ctx;
0808 compressor->base.embedded_panel_h_size = 0;
0809 compressor->base.embedded_panel_v_size = 0;
0810 compressor->base.memory_bus_width = ctx->asic_id.vram_width;
0811 compressor->base.allocated_size = 0;
0812 compressor->base.preferred_requested_size = 0;
0813 compressor->base.min_compress_ratio = FBC_COMPRESS_RATIO_INVALID;
0814 compressor->base.banks_num = 0;
0815 compressor->base.raw_size = 0;
0816 compressor->base.channel_interleave_size = 0;
0817 compressor->base.dram_channels_num = 0;
0818 compressor->base.lpt_channels_num = 0;
0819 compressor->base.attached_inst = 0;
0820 compressor->base.is_enabled = false;
0821
0822 if (BP_RESULT_OK ==
0823 bp->funcs->get_embedded_panel_info(bp, &panel_info)) {
0824 compressor->base.embedded_panel_h_size =
0825 panel_info.lcd_timing.horizontal_addressable;
0826 compressor->base.embedded_panel_v_size =
0827 panel_info.lcd_timing.vertical_addressable;
0828 }
0829 }
0830
0831 struct compressor *dce112_compressor_create(struct dc_context *ctx)
0832 {
0833 struct dce112_compressor *cp110 =
0834 kzalloc(sizeof(struct dce112_compressor), GFP_KERNEL);
0835
0836 if (!cp110)
0837 return NULL;
0838
0839 dce112_compressor_construct(cp110, ctx);
0840 return &cp110->base;
0841 }
0842
0843 void dce112_compressor_destroy(struct compressor **compressor)
0844 {
0845 kfree(TO_DCE112_COMPRESSOR(*compressor));
0846 *compressor = NULL;
0847 }