| .. | .. |
|---|
| 23 | 23 | * |
|---|
| 24 | 24 | */ |
|---|
| 25 | 25 | |
|---|
| 26 | +#include <linux/slab.h> |
|---|
| 27 | + |
|---|
| 26 | 28 | #include "dm_services.h" |
|---|
| 27 | 29 | #include "basics/conversion.h" |
|---|
| 28 | 30 | |
|---|
| .. | .. |
|---|
| 139 | 141 | params->flags.TRUNCATE_MODE); |
|---|
| 140 | 142 | } |
|---|
| 141 | 143 | |
|---|
| 144 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 145 | +/** |
|---|
| 146 | + * dce60_set_truncation |
|---|
| 147 | + * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp |
|---|
| 148 | + * 2) enable truncation |
|---|
| 149 | + * 3) HW remove 12bit FMT support for DCE11 power saving reason. |
|---|
| 150 | + */ |
|---|
| 151 | +static void dce60_set_truncation( |
|---|
| 152 | + struct dce110_opp *opp110, |
|---|
| 153 | + const struct bit_depth_reduction_params *params) |
|---|
| 154 | +{ |
|---|
| 155 | + /* DCE6 has no FMT_TRUNCATE_MODE bit in FMT_BIT_DEPTH_CONTROL reg */ |
|---|
| 156 | + |
|---|
| 157 | + /*Disable truncation*/ |
|---|
| 158 | + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, |
|---|
| 159 | + FMT_TRUNCATE_EN, 0, |
|---|
| 160 | + FMT_TRUNCATE_DEPTH, 0); |
|---|
| 161 | + |
|---|
| 162 | + if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) { |
|---|
| 163 | + /* 8bpc trunc on YCbCr422*/ |
|---|
| 164 | + if (params->flags.TRUNCATE_DEPTH == 1) |
|---|
| 165 | + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, |
|---|
| 166 | + FMT_TRUNCATE_EN, 1, |
|---|
| 167 | + FMT_TRUNCATE_DEPTH, 1); |
|---|
| 168 | + else if (params->flags.TRUNCATE_DEPTH == 2) |
|---|
| 169 | + /* 10bpc trunc on YCbCr422*/ |
|---|
| 170 | + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, |
|---|
| 171 | + FMT_TRUNCATE_EN, 1, |
|---|
| 172 | + FMT_TRUNCATE_DEPTH, 2); |
|---|
| 173 | + return; |
|---|
| 174 | + } |
|---|
| 175 | + /* on other format-to do */ |
|---|
| 176 | + if (params->flags.TRUNCATE_ENABLED == 0) |
|---|
| 177 | + return; |
|---|
| 178 | + /*Set truncation depth and Enable truncation*/ |
|---|
| 179 | + REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL, |
|---|
| 180 | + FMT_TRUNCATE_EN, 1, |
|---|
| 181 | + FMT_TRUNCATE_DEPTH, |
|---|
| 182 | + params->flags.TRUNCATE_DEPTH); |
|---|
| 183 | +} |
|---|
| 184 | +#endif |
|---|
| 142 | 185 | |
|---|
| 143 | 186 | /** |
|---|
| 144 | 187 | * set_spatial_dither |
|---|
| .. | .. |
|---|
| 371 | 414 | } |
|---|
| 372 | 415 | } |
|---|
| 373 | 416 | |
|---|
| 417 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 418 | +/** |
|---|
| 419 | + * Set Clamping for DCE6 parts |
|---|
| 420 | + * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping) |
|---|
| 421 | + * 1 for 8 bpc |
|---|
| 422 | + * 2 for 10 bpc |
|---|
| 423 | + * 3 for 12 bpc |
|---|
| 424 | + * 7 for programable |
|---|
| 425 | + * 2) Enable clamp if Limited range requested |
|---|
| 426 | + */ |
|---|
| 427 | +void dce60_opp_set_clamping( |
|---|
| 428 | + struct dce110_opp *opp110, |
|---|
| 429 | + const struct clamping_and_pixel_encoding_params *params) |
|---|
| 430 | +{ |
|---|
| 431 | + REG_SET_2(FMT_CLAMP_CNTL, 0, |
|---|
| 432 | + FMT_CLAMP_DATA_EN, 0, |
|---|
| 433 | + FMT_CLAMP_COLOR_FORMAT, 0); |
|---|
| 434 | + |
|---|
| 435 | + switch (params->clamping_level) { |
|---|
| 436 | + case CLAMPING_FULL_RANGE: |
|---|
| 437 | + break; |
|---|
| 438 | + case CLAMPING_LIMITED_RANGE_8BPC: |
|---|
| 439 | + REG_SET_2(FMT_CLAMP_CNTL, 0, |
|---|
| 440 | + FMT_CLAMP_DATA_EN, 1, |
|---|
| 441 | + FMT_CLAMP_COLOR_FORMAT, 1); |
|---|
| 442 | + break; |
|---|
| 443 | + case CLAMPING_LIMITED_RANGE_10BPC: |
|---|
| 444 | + REG_SET_2(FMT_CLAMP_CNTL, 0, |
|---|
| 445 | + FMT_CLAMP_DATA_EN, 1, |
|---|
| 446 | + FMT_CLAMP_COLOR_FORMAT, 2); |
|---|
| 447 | + break; |
|---|
| 448 | + case CLAMPING_LIMITED_RANGE_12BPC: |
|---|
| 449 | + REG_SET_2(FMT_CLAMP_CNTL, 0, |
|---|
| 450 | + FMT_CLAMP_DATA_EN, 1, |
|---|
| 451 | + FMT_CLAMP_COLOR_FORMAT, 3); |
|---|
| 452 | + break; |
|---|
| 453 | + case CLAMPING_LIMITED_RANGE_PROGRAMMABLE: |
|---|
| 454 | + /*Set clamp control*/ |
|---|
| 455 | + REG_SET_2(FMT_CLAMP_CNTL, 0, |
|---|
| 456 | + FMT_CLAMP_DATA_EN, 1, |
|---|
| 457 | + FMT_CLAMP_COLOR_FORMAT, 7); |
|---|
| 458 | + |
|---|
| 459 | + /* DCE6 does have FMT_CLAMP_COMPONENT_{R,G,B} registers */ |
|---|
| 460 | + |
|---|
| 461 | + break; |
|---|
| 462 | + default: |
|---|
| 463 | + break; |
|---|
| 464 | + } |
|---|
| 465 | +} |
|---|
| 466 | +#endif |
|---|
| 467 | + |
|---|
| 374 | 468 | /** |
|---|
| 375 | 469 | * set_pixel_encoding |
|---|
| 376 | 470 | * |
|---|
| .. | .. |
|---|
| 406 | 500 | |
|---|
| 407 | 501 | } |
|---|
| 408 | 502 | |
|---|
| 503 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 504 | +/** |
|---|
| 505 | + * dce60_set_pixel_encoding |
|---|
| 506 | + * DCE6 has no FMT_SUBSAMPLING_{MODE,ORDER} bits in FMT_CONTROL reg |
|---|
| 507 | + * Set Pixel Encoding |
|---|
| 508 | + * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly |
|---|
| 509 | + * 1: YCbCr 4:2:2 |
|---|
| 510 | + */ |
|---|
| 511 | +static void dce60_set_pixel_encoding( |
|---|
| 512 | + struct dce110_opp *opp110, |
|---|
| 513 | + const struct clamping_and_pixel_encoding_params *params) |
|---|
| 514 | +{ |
|---|
| 515 | + if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS) |
|---|
| 516 | + REG_UPDATE_2(FMT_CONTROL, |
|---|
| 517 | + FMT_PIXEL_ENCODING, 0, |
|---|
| 518 | + FMT_CBCR_BIT_REDUCTION_BYPASS, 0); |
|---|
| 519 | + else |
|---|
| 520 | + REG_UPDATE(FMT_CONTROL, |
|---|
| 521 | + FMT_PIXEL_ENCODING, 0); |
|---|
| 522 | + |
|---|
| 523 | + if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) { |
|---|
| 524 | + REG_UPDATE(FMT_CONTROL, |
|---|
| 525 | + FMT_PIXEL_ENCODING, 1); |
|---|
| 526 | + } |
|---|
| 527 | + if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) { |
|---|
| 528 | + REG_UPDATE_2(FMT_CONTROL, |
|---|
| 529 | + FMT_PIXEL_ENCODING, 2, |
|---|
| 530 | + FMT_CBCR_BIT_REDUCTION_BYPASS, 1); |
|---|
| 531 | + } |
|---|
| 532 | + |
|---|
| 533 | +} |
|---|
| 534 | +#endif |
|---|
| 535 | + |
|---|
| 409 | 536 | void dce110_opp_program_bit_depth_reduction( |
|---|
| 410 | 537 | struct output_pixel_processor *opp, |
|---|
| 411 | 538 | const struct bit_depth_reduction_params *params) |
|---|
| .. | .. |
|---|
| 417 | 544 | set_temporal_dither(opp110, params); |
|---|
| 418 | 545 | } |
|---|
| 419 | 546 | |
|---|
| 547 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 548 | +void dce60_opp_program_bit_depth_reduction( |
|---|
| 549 | + struct output_pixel_processor *opp, |
|---|
| 550 | + const struct bit_depth_reduction_params *params) |
|---|
| 551 | +{ |
|---|
| 552 | + struct dce110_opp *opp110 = TO_DCE110_OPP(opp); |
|---|
| 553 | + |
|---|
| 554 | + dce60_set_truncation(opp110, params); |
|---|
| 555 | + set_spatial_dither(opp110, params); |
|---|
| 556 | + set_temporal_dither(opp110, params); |
|---|
| 557 | +} |
|---|
| 558 | +#endif |
|---|
| 559 | + |
|---|
| 420 | 560 | void dce110_opp_program_clamping_and_pixel_encoding( |
|---|
| 421 | 561 | struct output_pixel_processor *opp, |
|---|
| 422 | 562 | const struct clamping_and_pixel_encoding_params *params) |
|---|
| .. | .. |
|---|
| 426 | 566 | dce110_opp_set_clamping(opp110, params); |
|---|
| 427 | 567 | set_pixel_encoding(opp110, params); |
|---|
| 428 | 568 | } |
|---|
| 569 | + |
|---|
| 570 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 571 | +void dce60_opp_program_clamping_and_pixel_encoding( |
|---|
| 572 | + struct output_pixel_processor *opp, |
|---|
| 573 | + const struct clamping_and_pixel_encoding_params *params) |
|---|
| 574 | +{ |
|---|
| 575 | + struct dce110_opp *opp110 = TO_DCE110_OPP(opp); |
|---|
| 576 | + |
|---|
| 577 | + dce60_opp_set_clamping(opp110, params); |
|---|
| 578 | + dce60_set_pixel_encoding(opp110, params); |
|---|
| 579 | +} |
|---|
| 580 | +#endif |
|---|
| 581 | + |
|---|
| 429 | 582 | |
|---|
| 430 | 583 | static void program_formatter_420_memory(struct output_pixel_processor *opp) |
|---|
| 431 | 584 | { |
|---|
| .. | .. |
|---|
| 524 | 677 | return; |
|---|
| 525 | 678 | } |
|---|
| 526 | 679 | |
|---|
| 680 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 681 | +void dce60_opp_program_fmt( |
|---|
| 682 | + struct output_pixel_processor *opp, |
|---|
| 683 | + struct bit_depth_reduction_params *fmt_bit_depth, |
|---|
| 684 | + struct clamping_and_pixel_encoding_params *clamping) |
|---|
| 685 | +{ |
|---|
| 686 | + /* dithering is affected by <CrtcSourceSelect>, hence should be |
|---|
| 687 | + * programmed afterwards */ |
|---|
| 527 | 688 | |
|---|
| 689 | + if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
|---|
| 690 | + program_formatter_420_memory(opp); |
|---|
| 691 | + |
|---|
| 692 | + dce60_opp_program_bit_depth_reduction( |
|---|
| 693 | + opp, |
|---|
| 694 | + fmt_bit_depth); |
|---|
| 695 | + |
|---|
| 696 | + dce60_opp_program_clamping_and_pixel_encoding( |
|---|
| 697 | + opp, |
|---|
| 698 | + clamping); |
|---|
| 699 | + |
|---|
| 700 | + if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
|---|
| 701 | + program_formatter_reset_dig_resync_fifo(opp); |
|---|
| 702 | + |
|---|
| 703 | + return; |
|---|
| 704 | +} |
|---|
| 705 | +#endif |
|---|
| 528 | 706 | |
|---|
| 529 | 707 | |
|---|
| 530 | 708 | |
|---|
| .. | .. |
|---|
| 538 | 716 | .opp_program_fmt = dce110_opp_program_fmt, |
|---|
| 539 | 717 | .opp_program_bit_depth_reduction = dce110_opp_program_bit_depth_reduction |
|---|
| 540 | 718 | }; |
|---|
| 719 | + |
|---|
| 720 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 721 | +static const struct opp_funcs dce60_opp_funcs = { |
|---|
| 722 | + .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion, |
|---|
| 723 | + .opp_destroy = dce110_opp_destroy, |
|---|
| 724 | + .opp_program_fmt = dce60_opp_program_fmt, |
|---|
| 725 | + .opp_program_bit_depth_reduction = dce60_opp_program_bit_depth_reduction |
|---|
| 726 | +}; |
|---|
| 727 | +#endif |
|---|
| 541 | 728 | |
|---|
| 542 | 729 | void dce110_opp_construct(struct dce110_opp *opp110, |
|---|
| 543 | 730 | struct dc_context *ctx, |
|---|
| .. | .. |
|---|
| 557 | 744 | opp110->opp_mask = opp_mask; |
|---|
| 558 | 745 | } |
|---|
| 559 | 746 | |
|---|
| 747 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 748 | +void dce60_opp_construct(struct dce110_opp *opp110, |
|---|
| 749 | + struct dc_context *ctx, |
|---|
| 750 | + uint32_t inst, |
|---|
| 751 | + const struct dce_opp_registers *regs, |
|---|
| 752 | + const struct dce_opp_shift *opp_shift, |
|---|
| 753 | + const struct dce_opp_mask *opp_mask) |
|---|
| 754 | +{ |
|---|
| 755 | + opp110->base.funcs = &dce60_opp_funcs; |
|---|
| 756 | + |
|---|
| 757 | + opp110->base.ctx = ctx; |
|---|
| 758 | + |
|---|
| 759 | + opp110->base.inst = inst; |
|---|
| 760 | + |
|---|
| 761 | + opp110->regs = regs; |
|---|
| 762 | + opp110->opp_shift = opp_shift; |
|---|
| 763 | + opp110->opp_mask = opp_mask; |
|---|
| 764 | +} |
|---|
| 765 | +#endif |
|---|
| 766 | + |
|---|
| 560 | 767 | void dce110_opp_destroy(struct output_pixel_processor **opp) |
|---|
| 561 | 768 | { |
|---|
| 562 | 769 | if (*opp) |
|---|