LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dce - dce_opp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 121 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 13 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2012-15 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  * Authors: AMD
      23             :  *
      24             :  */
      25             : 
      26             : #include "dm_services.h"
      27             : #include "basics/conversion.h"
      28             : 
      29             : #include "dce_opp.h"
      30             : 
      31             : #include "reg_helper.h"
      32             : 
      33             : #define REG(reg)\
      34             :         (opp110->regs->reg)
      35             : 
      36             : #undef FN
      37             : #define FN(reg_name, field_name) \
      38             :         opp110->opp_shift->field_name, opp110->opp_mask->field_name
      39             : 
      40             : #define CTX \
      41             :         opp110->base.ctx
      42             : 
      43             : enum {
      44             :         MAX_PWL_ENTRY = 128,
      45             :         MAX_REGIONS_NUMBER = 16
      46             : };
      47             : 
      48             : enum {
      49             :         MAX_LUT_ENTRY = 256,
      50             :         MAX_NUMBER_OF_ENTRIES = 256
      51             : };
      52             : 
      53             : 
      54             : enum {
      55             :         OUTPUT_CSC_MATRIX_SIZE = 12
      56             : };
      57             : 
      58             : 
      59             : 
      60             : 
      61             : 
      62             : 
      63             : 
      64             : 
      65             : 
      66             : 
      67             : 
      68             : 
      69             : 
      70             : 
      71             : 
      72             : 
      73             : 
      74             : 
      75             : 
      76             : 
      77             : 
      78             : 
      79             : /*
      80             :  *****************************************************************************
      81             :  *  Function: regamma_config_regions_and_segments
      82             :  *
      83             :  *     build regamma curve by using predefined hw points
      84             :  *     uses interface parameters ,like EDID coeff.
      85             :  *
      86             :  * @param   : parameters   interface parameters
      87             :  *  @return void
      88             :  *
      89             :  *  @note
      90             :  *
      91             :  *  @see
      92             :  *
      93             :  *****************************************************************************
      94             :  */
      95             : 
      96             : 
      97             : 
      98             : /*
      99             :  *      set_truncation
     100             :  *      1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
     101             :  *      2) enable truncation
     102             :  *      3) HW remove 12bit FMT support for DCE11 power saving reason.
     103             :  */
     104           0 : static void set_truncation(
     105             :                 struct dce110_opp *opp110,
     106             :                 const struct bit_depth_reduction_params *params)
     107             : {
     108             :         /*Disable truncation*/
     109           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     110             :                         FMT_TRUNCATE_EN, 0,
     111             :                         FMT_TRUNCATE_DEPTH, 0,
     112             :                         FMT_TRUNCATE_MODE, 0);
     113             : 
     114             : 
     115           0 :         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
     116             :                 /*  8bpc trunc on YCbCr422*/
     117           0 :                 if (params->flags.TRUNCATE_DEPTH == 1)
     118           0 :                         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     119             :                                         FMT_TRUNCATE_EN, 1,
     120             :                                         FMT_TRUNCATE_DEPTH, 1,
     121             :                                         FMT_TRUNCATE_MODE, 0);
     122           0 :                 else if (params->flags.TRUNCATE_DEPTH == 2)
     123             :                         /*  10bpc trunc on YCbCr422*/
     124           0 :                         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     125             :                                         FMT_TRUNCATE_EN, 1,
     126             :                                         FMT_TRUNCATE_DEPTH, 2,
     127             :                                         FMT_TRUNCATE_MODE, 0);
     128             :                 return;
     129             :         }
     130             :         /* on other format-to do */
     131           0 :         if (params->flags.TRUNCATE_ENABLED == 0)
     132             :                 return;
     133             :         /*Set truncation depth and Enable truncation*/
     134           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     135             :                                 FMT_TRUNCATE_EN, 1,
     136             :                                 FMT_TRUNCATE_DEPTH,
     137             :                                 params->flags.TRUNCATE_DEPTH,
     138             :                                 FMT_TRUNCATE_MODE,
     139             :                                 params->flags.TRUNCATE_MODE);
     140             : }
     141             : 
     142             : #if defined(CONFIG_DRM_AMD_DC_SI)
     143             : /*
     144             :  *      dce60_set_truncation
     145             :  *      1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
     146             :  *      2) enable truncation
     147             :  *      3) HW remove 12bit FMT support for DCE11 power saving reason.
     148             :  */
     149             : static void dce60_set_truncation(
     150             :                 struct dce110_opp *opp110,
     151             :                 const struct bit_depth_reduction_params *params)
     152             : {
     153             :         /* DCE6 has no FMT_TRUNCATE_MODE bit in FMT_BIT_DEPTH_CONTROL reg */
     154             : 
     155             :         /*Disable truncation*/
     156             :         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
     157             :                         FMT_TRUNCATE_EN, 0,
     158             :                         FMT_TRUNCATE_DEPTH, 0);
     159             : 
     160             :         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
     161             :                 /*  8bpc trunc on YCbCr422*/
     162             :                 if (params->flags.TRUNCATE_DEPTH == 1)
     163             :                         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
     164             :                                         FMT_TRUNCATE_EN, 1,
     165             :                                         FMT_TRUNCATE_DEPTH, 1);
     166             :                 else if (params->flags.TRUNCATE_DEPTH == 2)
     167             :                         /*  10bpc trunc on YCbCr422*/
     168             :                         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
     169             :                                         FMT_TRUNCATE_EN, 1,
     170             :                                         FMT_TRUNCATE_DEPTH, 2);
     171             :                 return;
     172             :         }
     173             :         /* on other format-to do */
     174             :         if (params->flags.TRUNCATE_ENABLED == 0)
     175             :                 return;
     176             :         /*Set truncation depth and Enable truncation*/
     177             :         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
     178             :                                 FMT_TRUNCATE_EN, 1,
     179             :                                 FMT_TRUNCATE_DEPTH,
     180             :                                 params->flags.TRUNCATE_DEPTH);
     181             : }
     182             : #endif
     183             : 
     184             : /*
     185             :  *      set_spatial_dither
     186             :  *      1) set spatial dithering mode: pattern of seed
     187             :  *      2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp
     188             :  *      3) set random seed
     189             :  *      4) set random mode
     190             :  *              lfsr is reset every frame or not reset
     191             :  *              RGB dithering method
     192             :  *              0: RGB data are all dithered with x^28+x^3+1
     193             :  *              1: R data is dithered with x^28+x^3+1
     194             :  *              G data is dithered with x^28+X^9+1
     195             :  *              B data is dithered with x^28+x^13+1
     196             :  *              enable high pass filter or not
     197             :  *      5) enable spatical dithering
     198             :  */
     199           0 : static void set_spatial_dither(
     200             :         struct dce110_opp *opp110,
     201             :         const struct bit_depth_reduction_params *params)
     202             : {
     203             :         /*Disable spatial (random) dithering*/
     204           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     205             :                 FMT_SPATIAL_DITHER_EN, 0,
     206             :                 FMT_SPATIAL_DITHER_DEPTH, 0,
     207             :                 FMT_SPATIAL_DITHER_MODE, 0);
     208             : 
     209           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     210             :                 FMT_HIGHPASS_RANDOM_ENABLE, 0,
     211             :                 FMT_FRAME_RANDOM_ENABLE, 0,
     212             :                 FMT_RGB_RANDOM_ENABLE, 0);
     213             : 
     214           0 :         REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
     215             :                 FMT_TEMPORAL_DITHER_EN, 0);
     216             : 
     217           0 :         if (params->flags.SPATIAL_DITHER_ENABLED == 0)
     218             :                 return;
     219             : 
     220             :         /* only use FRAME_COUNTER_MAX if frameRandom == 1*/
     221             : 
     222           0 :         if (opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX &&
     223           0 :                         opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP) {
     224           0 :                 if (params->flags.FRAME_RANDOM == 1) {
     225           0 :                         if (params->flags.SPATIAL_DITHER_DEPTH == 0 ||
     226             :                         params->flags.SPATIAL_DITHER_DEPTH == 1) {
     227           0 :                                 REG_UPDATE_2(FMT_CONTROL,
     228             :                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,
     229             :                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);
     230           0 :                         } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
     231           0 :                                 REG_UPDATE_2(FMT_CONTROL,
     232             :                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,
     233             :                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);
     234             :                         } else
     235             :                                 return;
     236             :                 } else {
     237           0 :                         REG_UPDATE_2(FMT_CONTROL,
     238             :                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,
     239             :                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);
     240             :                 }
     241             :         }
     242             :         /* Set seed for random values for
     243             :          * spatial dithering for R,G,B channels
     244             :          */
     245           0 :         REG_UPDATE(FMT_DITHER_RAND_R_SEED,
     246             :                         FMT_RAND_R_SEED, params->r_seed_value);
     247             : 
     248           0 :         REG_UPDATE(FMT_DITHER_RAND_G_SEED,
     249             :                         FMT_RAND_G_SEED, params->g_seed_value);
     250             : 
     251           0 :         REG_UPDATE(FMT_DITHER_RAND_B_SEED,
     252             :                         FMT_RAND_B_SEED, params->b_seed_value);
     253             : 
     254             :         /* FMT_OFFSET_R_Cr  31:16 0x0 Setting the zero
     255             :          * offset for the R/Cr channel, lower 4LSB
     256             :          * is forced to zeros. Typically set to 0
     257             :          * RGB and 0x80000 YCbCr.
     258             :          */
     259             :         /* FMT_OFFSET_G_Y   31:16 0x0 Setting the zero
     260             :          * offset for the G/Y  channel, lower 4LSB is
     261             :          * forced to zeros. Typically set to 0 RGB
     262             :          * and 0x80000 YCbCr.
     263             :          */
     264             :         /* FMT_OFFSET_B_Cb  31:16 0x0 Setting the zero
     265             :          * offset for the B/Cb channel, lower 4LSB is
     266             :          * forced to zeros. Typically set to 0 RGB and
     267             :          * 0x80000 YCbCr.
     268             :          */
     269             : 
     270             :         /* Disable High pass filter
     271             :          * Reset only at startup
     272             :          * Set RGB data dithered with x^28+x^3+1
     273             :          */
     274           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     275             :                 FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,
     276             :                 FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,
     277             :                 FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);
     278             : 
     279             :         /* Set spatial dithering bit depth
     280             :          * Set spatial dithering mode
     281             :          * (default is Seed patterrn AAAA...)
     282             :          * Enable spatial dithering
     283             :          */
     284           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     285             :                 FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,
     286             :                 FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,
     287             :                 FMT_SPATIAL_DITHER_EN, 1);
     288             : }
     289             : 
     290             : /*
     291             :  *      SetTemporalDither (Frame Modulation)
     292             :  *      1) set temporal dither depth
     293             :  *      2) select pattern: from hard-coded pattern or programmable pattern
     294             :  *      3) select optimized strips for BGR or RGB LCD sub-pixel
     295             :  *      4) set s matrix
     296             :  *      5) set t matrix
     297             :  *      6) set grey level for 0.25, 0.5, 0.75
     298             :  *      7) enable temporal dithering
     299             :  */
     300             : 
     301           0 : static void set_temporal_dither(
     302             :         struct dce110_opp *opp110,
     303             :         const struct bit_depth_reduction_params *params)
     304             : {
     305             :         /*Disable temporal (frame modulation) dithering first*/
     306           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     307             :                 FMT_TEMPORAL_DITHER_EN, 0,
     308             :                 FMT_TEMPORAL_DITHER_RESET, 0,
     309             :                 FMT_TEMPORAL_DITHER_OFFSET, 0);
     310             : 
     311           0 :         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
     312             :                 FMT_TEMPORAL_DITHER_DEPTH, 0,
     313             :                 FMT_TEMPORAL_LEVEL, 0);
     314             : 
     315           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     316             :                 FMT_25FRC_SEL, 0,
     317             :                 FMT_50FRC_SEL, 0,
     318             :                 FMT_75FRC_SEL, 0);
     319             : 
     320             :         /* no 10bpc dither on DCE11*/
     321           0 :         if (params->flags.FRAME_MODULATION_ENABLED == 0 ||
     322           0 :                 params->flags.FRAME_MODULATION_DEPTH == 2)
     323             :                 return;
     324             : 
     325             :         /* Set temporal dithering depth*/
     326           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     327             :                 FMT_TEMPORAL_DITHER_DEPTH, params->flags.FRAME_MODULATION_DEPTH,
     328             :                 FMT_TEMPORAL_DITHER_RESET, 0,
     329             :                 FMT_TEMPORAL_DITHER_OFFSET, 0);
     330             : 
     331             :         /*Select legacy pattern based on FRC and Temporal level*/
     332           0 :         if (REG(FMT_TEMPORAL_DITHER_PATTERN_CONTROL)) {
     333           0 :                 REG_WRITE(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, 0);
     334             :                 /*Set s matrix*/
     335           0 :                 REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, 0);
     336             :                 /*Set t matrix*/
     337           0 :                 REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, 0);
     338             :         }
     339             : 
     340             :         /*Select patterns for 0.25, 0.5 and 0.75 grey level*/
     341           0 :         REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
     342             :                 FMT_TEMPORAL_LEVEL, params->flags.TEMPORAL_LEVEL);
     343             : 
     344           0 :         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
     345             :                 FMT_25FRC_SEL, params->flags.FRC25,
     346             :                 FMT_50FRC_SEL, params->flags.FRC50,
     347             :                 FMT_75FRC_SEL, params->flags.FRC75);
     348             : 
     349             :         /*Enable bit reduction by temporal (frame modulation) dithering*/
     350           0 :         REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
     351             :                 FMT_TEMPORAL_DITHER_EN, 1);
     352             : }
     353             : 
     354             : /*
     355             :  *      Set Clamping
     356             :  *      1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
     357             :  *              1 for 8 bpc
     358             :  *              2 for 10 bpc
     359             :  *              3 for 12 bpc
     360             :  *              7 for programable
     361             :  *      2) Enable clamp if Limited range requested
     362             :  */
     363           0 : void dce110_opp_set_clamping(
     364             :         struct dce110_opp *opp110,
     365             :         const struct clamping_and_pixel_encoding_params *params)
     366             : {
     367           0 :         REG_SET_2(FMT_CLAMP_CNTL, 0,
     368             :                 FMT_CLAMP_DATA_EN, 0,
     369             :                 FMT_CLAMP_COLOR_FORMAT, 0);
     370             : 
     371           0 :         switch (params->clamping_level) {
     372             :         case CLAMPING_FULL_RANGE:
     373             :                 break;
     374             :         case CLAMPING_LIMITED_RANGE_8BPC:
     375           0 :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     376             :                         FMT_CLAMP_DATA_EN, 1,
     377             :                         FMT_CLAMP_COLOR_FORMAT, 1);
     378           0 :                 break;
     379             :         case CLAMPING_LIMITED_RANGE_10BPC:
     380           0 :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     381             :                         FMT_CLAMP_DATA_EN, 1,
     382             :                         FMT_CLAMP_COLOR_FORMAT, 2);
     383           0 :                 break;
     384             :         case CLAMPING_LIMITED_RANGE_12BPC:
     385           0 :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     386             :                         FMT_CLAMP_DATA_EN, 1,
     387             :                         FMT_CLAMP_COLOR_FORMAT, 3);
     388           0 :                 break;
     389             :         case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
     390             :                 /*Set clamp control*/
     391           0 :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     392             :                         FMT_CLAMP_DATA_EN, 1,
     393             :                         FMT_CLAMP_COLOR_FORMAT, 7);
     394             : 
     395             :                 /*set the defaults*/
     396           0 :                 REG_SET_2(FMT_CLAMP_COMPONENT_R, 0,
     397             :                         FMT_CLAMP_LOWER_R, 0x10,
     398             :                         FMT_CLAMP_UPPER_R, 0xFEF);
     399             : 
     400           0 :                 REG_SET_2(FMT_CLAMP_COMPONENT_G, 0,
     401             :                         FMT_CLAMP_LOWER_G, 0x10,
     402             :                         FMT_CLAMP_UPPER_G, 0xFEF);
     403             : 
     404           0 :                 REG_SET_2(FMT_CLAMP_COMPONENT_B, 0,
     405             :                         FMT_CLAMP_LOWER_B, 0x10,
     406             :                         FMT_CLAMP_UPPER_B, 0xFEF);
     407           0 :                 break;
     408             :         default:
     409             :                 break;
     410             :         }
     411           0 : }
     412             : 
     413             : #if defined(CONFIG_DRM_AMD_DC_SI)
     414             : /*
     415             :  *      Set Clamping for DCE6 parts
     416             :  *      1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
     417             :  *              1 for 8 bpc
     418             :  *              2 for 10 bpc
     419             :  *              3 for 12 bpc
     420             :  *              7 for programable
     421             :  *      2) Enable clamp if Limited range requested
     422             :  */
     423             : static void dce60_opp_set_clamping(
     424             :         struct dce110_opp *opp110,
     425             :         const struct clamping_and_pixel_encoding_params *params)
     426             : {
     427             :         REG_SET_2(FMT_CLAMP_CNTL, 0,
     428             :                 FMT_CLAMP_DATA_EN, 0,
     429             :                 FMT_CLAMP_COLOR_FORMAT, 0);
     430             : 
     431             :         switch (params->clamping_level) {
     432             :         case CLAMPING_FULL_RANGE:
     433             :                 break;
     434             :         case CLAMPING_LIMITED_RANGE_8BPC:
     435             :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     436             :                         FMT_CLAMP_DATA_EN, 1,
     437             :                         FMT_CLAMP_COLOR_FORMAT, 1);
     438             :                 break;
     439             :         case CLAMPING_LIMITED_RANGE_10BPC:
     440             :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     441             :                         FMT_CLAMP_DATA_EN, 1,
     442             :                         FMT_CLAMP_COLOR_FORMAT, 2);
     443             :                 break;
     444             :         case CLAMPING_LIMITED_RANGE_12BPC:
     445             :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     446             :                         FMT_CLAMP_DATA_EN, 1,
     447             :                         FMT_CLAMP_COLOR_FORMAT, 3);
     448             :                 break;
     449             :         case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
     450             :                 /*Set clamp control*/
     451             :                 REG_SET_2(FMT_CLAMP_CNTL, 0,
     452             :                         FMT_CLAMP_DATA_EN, 1,
     453             :                         FMT_CLAMP_COLOR_FORMAT, 7);
     454             : 
     455             :                 /* DCE6 does have FMT_CLAMP_COMPONENT_{R,G,B} registers */
     456             : 
     457             :                 break;
     458             :         default:
     459             :                 break;
     460             :         }
     461             : }
     462             : #endif
     463             : 
     464             : /*
     465             :  *      set_pixel_encoding
     466             :  *
     467             :  *      Set Pixel Encoding
     468             :  *              0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
     469             :  *              1: YCbCr 4:2:2
     470             :  */
     471           0 : static void set_pixel_encoding(
     472             :         struct dce110_opp *opp110,
     473             :         const struct clamping_and_pixel_encoding_params *params)
     474             : {
     475           0 :         if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS)
     476           0 :                 REG_UPDATE_3(FMT_CONTROL,
     477             :                                 FMT_PIXEL_ENCODING, 0,
     478             :                                 FMT_SUBSAMPLING_MODE, 0,
     479             :                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 0);
     480             :         else
     481           0 :                 REG_UPDATE_2(FMT_CONTROL,
     482             :                                 FMT_PIXEL_ENCODING, 0,
     483             :                                 FMT_SUBSAMPLING_MODE, 0);
     484             : 
     485           0 :         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
     486           0 :                 REG_UPDATE_2(FMT_CONTROL,
     487             :                                 FMT_PIXEL_ENCODING, 1,
     488             :                                 FMT_SUBSAMPLING_ORDER, 0);
     489             :         }
     490           0 :         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
     491           0 :                 REG_UPDATE_3(FMT_CONTROL,
     492             :                                 FMT_PIXEL_ENCODING, 2,
     493             :                                 FMT_SUBSAMPLING_MODE, 2,
     494             :                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 1);
     495             :         }
     496             : 
     497           0 : }
     498             : 
     499             : #if defined(CONFIG_DRM_AMD_DC_SI)
     500             : /*
     501             :  *      dce60_set_pixel_encoding
     502             :  *      DCE6 has no FMT_SUBSAMPLING_{MODE,ORDER} bits in FMT_CONTROL reg
     503             :  *      Set Pixel Encoding
     504             :  *              0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
     505             :  *              1: YCbCr 4:2:2
     506             :  */
     507             : static void dce60_set_pixel_encoding(
     508             :         struct dce110_opp *opp110,
     509             :         const struct clamping_and_pixel_encoding_params *params)
     510             : {
     511             :         if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS)
     512             :                 REG_UPDATE_2(FMT_CONTROL,
     513             :                                 FMT_PIXEL_ENCODING, 0,
     514             :                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 0);
     515             :         else
     516             :                 REG_UPDATE(FMT_CONTROL,
     517             :                                 FMT_PIXEL_ENCODING, 0);
     518             : 
     519             :         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
     520             :                 REG_UPDATE(FMT_CONTROL,
     521             :                                 FMT_PIXEL_ENCODING, 1);
     522             :         }
     523             :         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
     524             :                 REG_UPDATE_2(FMT_CONTROL,
     525             :                                 FMT_PIXEL_ENCODING, 2,
     526             :                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 1);
     527             :         }
     528             : 
     529             : }
     530             : #endif
     531             : 
     532           0 : void dce110_opp_program_bit_depth_reduction(
     533             :         struct output_pixel_processor *opp,
     534             :         const struct bit_depth_reduction_params *params)
     535             : {
     536           0 :         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
     537             : 
     538           0 :         set_truncation(opp110, params);
     539           0 :         set_spatial_dither(opp110, params);
     540           0 :         set_temporal_dither(opp110, params);
     541           0 : }
     542             : 
     543             : #if defined(CONFIG_DRM_AMD_DC_SI)
     544             : static void dce60_opp_program_bit_depth_reduction(
     545             :         struct output_pixel_processor *opp,
     546             :         const struct bit_depth_reduction_params *params)
     547             : {
     548             :         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
     549             : 
     550             :         dce60_set_truncation(opp110, params);
     551             :         set_spatial_dither(opp110, params);
     552             :         set_temporal_dither(opp110, params);
     553             : }
     554             : #endif
     555             : 
     556           0 : void dce110_opp_program_clamping_and_pixel_encoding(
     557             :         struct output_pixel_processor *opp,
     558             :         const struct clamping_and_pixel_encoding_params *params)
     559             : {
     560           0 :         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
     561             : 
     562           0 :         dce110_opp_set_clamping(opp110, params);
     563           0 :         set_pixel_encoding(opp110, params);
     564           0 : }
     565             : 
     566             : #if defined(CONFIG_DRM_AMD_DC_SI)
     567             : static void dce60_opp_program_clamping_and_pixel_encoding(
     568             :         struct output_pixel_processor *opp,
     569             :         const struct clamping_and_pixel_encoding_params *params)
     570             : {
     571             :         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
     572             : 
     573             :         dce60_opp_set_clamping(opp110, params);
     574             :         dce60_set_pixel_encoding(opp110, params);
     575             : }
     576             : #endif
     577             : 
     578             : 
     579           0 : static void program_formatter_420_memory(struct output_pixel_processor *opp)
     580             : {
     581           0 :         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
     582             :         uint32_t fmt_mem_cntl_value;
     583             : 
     584             :         /* Program source select*/
     585             :         /* Use HW default source select for FMT_MEMORYx_CONTROL */
     586             :         /* Use that value for FMT_SRC_SELECT as well*/
     587           0 :         REG_GET(CONTROL,
     588             :                         FMT420_MEM0_SOURCE_SEL, &fmt_mem_cntl_value);
     589             : 
     590           0 :         REG_UPDATE(FMT_CONTROL,
     591             :                         FMT_SRC_SELECT, fmt_mem_cntl_value);
     592             : 
     593             :         /* Turn on the memory */
     594           0 :         REG_UPDATE(CONTROL,
     595             :                         FMT420_MEM0_PWR_FORCE, 0);
     596           0 : }
     597             : 
     598           0 : void dce110_opp_set_dyn_expansion(
     599             :         struct output_pixel_processor *opp,
     600             :         enum dc_color_space color_sp,
     601             :         enum dc_color_depth color_dpth,
     602             :         enum signal_type signal)
     603             : {
     604           0 :         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
     605             : 
     606           0 :         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
     607             :                         FMT_DYNAMIC_EXP_EN, 0,
     608             :                         FMT_DYNAMIC_EXP_MODE, 0);
     609             : 
     610             :         /*00 - 10-bit -> 12-bit dynamic expansion*/
     611             :         /*01 - 8-bit  -> 12-bit dynamic expansion*/
     612           0 :         if (signal == SIGNAL_TYPE_HDMI_TYPE_A ||
     613           0 :                 signal == SIGNAL_TYPE_DISPLAY_PORT ||
     614             :                 signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
     615           0 :                 switch (color_dpth) {
     616             :                 case COLOR_DEPTH_888:
     617           0 :                         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
     618             :                                 FMT_DYNAMIC_EXP_EN, 1,
     619             :                                 FMT_DYNAMIC_EXP_MODE, 1);
     620           0 :                         break;
     621             :                 case COLOR_DEPTH_101010:
     622           0 :                         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
     623             :                                 FMT_DYNAMIC_EXP_EN, 1,
     624             :                                 FMT_DYNAMIC_EXP_MODE, 0);
     625           0 :                         break;
     626             :                 case COLOR_DEPTH_121212:
     627           0 :                         REG_UPDATE_2(
     628             :                                 FMT_DYNAMIC_EXP_CNTL,
     629             :                                 FMT_DYNAMIC_EXP_EN, 1,/*otherwise last two bits are zero*/
     630             :                                 FMT_DYNAMIC_EXP_MODE, 0);
     631           0 :                         break;
     632             :                 default:
     633             :                         break;
     634             :                 }
     635             :         }
     636           0 : }
     637             : 
     638           0 : static void program_formatter_reset_dig_resync_fifo(struct output_pixel_processor *opp)
     639             : {
     640           0 :         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
     641             : 
     642             :         /* clear previous phase lock status*/
     643           0 :         REG_UPDATE(FMT_CONTROL,
     644             :                         FMT_420_PIXEL_PHASE_LOCKED_CLEAR, 1);
     645             : 
     646             :         /* poll until FMT_420_PIXEL_PHASE_LOCKED become 1*/
     647           0 :         REG_WAIT(FMT_CONTROL, FMT_420_PIXEL_PHASE_LOCKED, 1, 10, 10);
     648             : 
     649           0 : }
     650             : 
     651           0 : void dce110_opp_program_fmt(
     652             :         struct output_pixel_processor *opp,
     653             :         struct bit_depth_reduction_params *fmt_bit_depth,
     654             :         struct clamping_and_pixel_encoding_params *clamping)
     655             : {
     656             :         /* dithering is affected by <CrtcSourceSelect>, hence should be
     657             :          * programmed afterwards */
     658             : 
     659           0 :         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
     660           0 :                 program_formatter_420_memory(opp);
     661             : 
     662           0 :         dce110_opp_program_bit_depth_reduction(
     663             :                 opp,
     664             :                 fmt_bit_depth);
     665             : 
     666           0 :         dce110_opp_program_clamping_and_pixel_encoding(
     667             :                 opp,
     668             :                 clamping);
     669             : 
     670           0 :         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
     671           0 :                 program_formatter_reset_dig_resync_fifo(opp);
     672             : 
     673           0 :         return;
     674             : }
     675             : 
     676             : #if defined(CONFIG_DRM_AMD_DC_SI)
     677             : static void dce60_opp_program_fmt(
     678             :         struct output_pixel_processor *opp,
     679             :         struct bit_depth_reduction_params *fmt_bit_depth,
     680             :         struct clamping_and_pixel_encoding_params *clamping)
     681             : {
     682             :         /* dithering is affected by <CrtcSourceSelect>, hence should be
     683             :          * programmed afterwards */
     684             : 
     685             :         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
     686             :                 program_formatter_420_memory(opp);
     687             : 
     688             :         dce60_opp_program_bit_depth_reduction(
     689             :                 opp,
     690             :                 fmt_bit_depth);
     691             : 
     692             :         dce60_opp_program_clamping_and_pixel_encoding(
     693             :                 opp,
     694             :                 clamping);
     695             : 
     696             :         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
     697             :                 program_formatter_reset_dig_resync_fifo(opp);
     698             : 
     699             :         return;
     700             : }
     701             : #endif
     702             : 
     703             : 
     704             : 
     705             : /*****************************************/
     706             : /* Constructor, Destructor               */
     707             : /*****************************************/
     708             : 
     709             : static const struct opp_funcs funcs = {
     710             :         .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
     711             :         .opp_destroy = dce110_opp_destroy,
     712             :         .opp_program_fmt = dce110_opp_program_fmt,
     713             :         .opp_program_bit_depth_reduction = dce110_opp_program_bit_depth_reduction
     714             : };
     715             : 
     716             : #if defined(CONFIG_DRM_AMD_DC_SI)
     717             : static const struct opp_funcs dce60_opp_funcs = {
     718             :         .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
     719             :         .opp_destroy = dce110_opp_destroy,
     720             :         .opp_program_fmt = dce60_opp_program_fmt,
     721             :         .opp_program_bit_depth_reduction = dce60_opp_program_bit_depth_reduction
     722             : };
     723             : #endif
     724             : 
     725           0 : void dce110_opp_construct(struct dce110_opp *opp110,
     726             :         struct dc_context *ctx,
     727             :         uint32_t inst,
     728             :         const struct dce_opp_registers *regs,
     729             :         const struct dce_opp_shift *opp_shift,
     730             :         const struct dce_opp_mask *opp_mask)
     731             : {
     732           0 :         opp110->base.funcs = &funcs;
     733             : 
     734           0 :         opp110->base.ctx = ctx;
     735             : 
     736           0 :         opp110->base.inst = inst;
     737             : 
     738           0 :         opp110->regs = regs;
     739           0 :         opp110->opp_shift = opp_shift;
     740           0 :         opp110->opp_mask = opp_mask;
     741           0 : }
     742             : 
     743             : #if defined(CONFIG_DRM_AMD_DC_SI)
     744             : void dce60_opp_construct(struct dce110_opp *opp110,
     745             :         struct dc_context *ctx,
     746             :         uint32_t inst,
     747             :         const struct dce_opp_registers *regs,
     748             :         const struct dce_opp_shift *opp_shift,
     749             :         const struct dce_opp_mask *opp_mask)
     750             : {
     751             :         opp110->base.funcs = &dce60_opp_funcs;
     752             : 
     753             :         opp110->base.ctx = ctx;
     754             : 
     755             :         opp110->base.inst = inst;
     756             : 
     757             :         opp110->regs = regs;
     758             :         opp110->opp_shift = opp_shift;
     759             :         opp110->opp_mask = opp_mask;
     760             : }
     761             : #endif
     762             : 
     763           0 : void dce110_opp_destroy(struct output_pixel_processor **opp)
     764             : {
     765           0 :         if (*opp)
     766           0 :                 kfree(FROM_DCE11_OPP(*opp));
     767           0 :         *opp = NULL;
     768           0 : }
     769             : 

Generated by: LCOV version 1.14