This source file includes following definitions.
- opp1_set_truncation
- opp1_set_spatial_dither
- opp1_program_bit_depth_reduction
- opp1_set_pixel_encoding
- opp1_set_clamping
- opp1_set_dyn_expansion
- opp1_program_clamping_and_pixel_encoding
- opp1_program_fmt
- opp1_program_stereo
- opp1_program_oppbuf
- opp1_pipe_clock_control
- opp1_destroy
- dcn10_opp_construct
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 #include <linux/slab.h>
  27 
  28 #include "dm_services.h"
  29 #include "dcn10_opp.h"
  30 #include "reg_helper.h"
  31 
  32 #define REG(reg) \
  33         (oppn10->regs->reg)
  34 
  35 #undef FN
  36 #define FN(reg_name, field_name) \
  37         oppn10->opp_shift->field_name, oppn10->opp_mask->field_name
  38 
  39 #define CTX \
  40         oppn10->base.ctx
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 static void opp1_set_truncation(
  52                 struct dcn10_opp *oppn10,
  53                 const struct bit_depth_reduction_params *params)
  54 {
  55         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
  56                 FMT_TRUNCATE_EN, params->flags.TRUNCATE_ENABLED,
  57                 FMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH,
  58                 FMT_TRUNCATE_MODE, params->flags.TRUNCATE_MODE);
  59 }
  60 
  61 static void opp1_set_spatial_dither(
  62         struct dcn10_opp *oppn10,
  63         const struct bit_depth_reduction_params *params)
  64 {
  65         
  66         REG_UPDATE_7(FMT_BIT_DEPTH_CONTROL,
  67                         FMT_SPATIAL_DITHER_EN, 0,
  68                         FMT_SPATIAL_DITHER_MODE, 0,
  69                         FMT_SPATIAL_DITHER_DEPTH, 0,
  70                         FMT_TEMPORAL_DITHER_EN, 0,
  71                         FMT_HIGHPASS_RANDOM_ENABLE, 0,
  72                         FMT_FRAME_RANDOM_ENABLE, 0,
  73                         FMT_RGB_RANDOM_ENABLE, 0);
  74 
  75 
  76         
  77         if (params->flags.FRAME_RANDOM == 1) {
  78                 if (params->flags.SPATIAL_DITHER_DEPTH == 0 || params->flags.SPATIAL_DITHER_DEPTH == 1) {
  79                         REG_UPDATE_2(FMT_CONTROL,
  80                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,
  81                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);
  82                 } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
  83                         REG_UPDATE_2(FMT_CONTROL,
  84                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,
  85                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);
  86                 } else {
  87                         return;
  88                 }
  89         } else {
  90                 REG_UPDATE_2(FMT_CONTROL,
  91                                 FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,
  92                                 FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);
  93         }
  94 
  95         
  96 
  97 
  98         REG_SET(FMT_DITHER_RAND_R_SEED, 0,
  99                         FMT_RAND_R_SEED, params->r_seed_value);
 100 
 101         REG_SET(FMT_DITHER_RAND_G_SEED, 0,
 102                         FMT_RAND_G_SEED, params->g_seed_value);
 103 
 104         REG_SET(FMT_DITHER_RAND_B_SEED, 0,
 105                         FMT_RAND_B_SEED, params->b_seed_value);
 106 
 107         
 108 
 109 
 110 
 111 
 112         
 113 
 114 
 115 
 116 
 117         
 118 
 119 
 120 
 121 
 122 
 123         REG_UPDATE_6(FMT_BIT_DEPTH_CONTROL,
 124                         
 125                         FMT_SPATIAL_DITHER_EN, params->flags.SPATIAL_DITHER_ENABLED,
 126                         
 127 
 128 
 129                         FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,
 130                         
 131                         FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,
 132                         
 133                         FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,
 134                         
 135                         FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,
 136                         
 137                         FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);
 138 }
 139 
 140 void opp1_program_bit_depth_reduction(
 141         struct output_pixel_processor *opp,
 142         const struct bit_depth_reduction_params *params)
 143 {
 144         struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
 145 
 146         opp1_set_truncation(oppn10, params);
 147         opp1_set_spatial_dither(oppn10, params);
 148         
 149 
 150 
 151 }
 152 
 153 
 154 
 155 
 156 
 157 
 158 
 159 
 160 static void opp1_set_pixel_encoding(
 161         struct dcn10_opp *oppn10,
 162         const struct clamping_and_pixel_encoding_params *params)
 163 {
 164         switch (params->pixel_encoding) {
 165 
 166         case PIXEL_ENCODING_RGB:
 167         case PIXEL_ENCODING_YCBCR444:
 168                 REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 0);
 169                 break;
 170         case PIXEL_ENCODING_YCBCR422:
 171                 REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 1);
 172                 break;
 173         case PIXEL_ENCODING_YCBCR420:
 174                 REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 2);
 175                 break;
 176         default:
 177                 break;
 178         }
 179 }
 180 
 181 
 182 
 183 
 184 
 185 
 186 
 187 
 188 
 189 
 190 static void opp1_set_clamping(
 191         struct dcn10_opp *oppn10,
 192         const struct clamping_and_pixel_encoding_params *params)
 193 {
 194         REG_UPDATE_2(FMT_CLAMP_CNTL,
 195                         FMT_CLAMP_DATA_EN, 0,
 196                         FMT_CLAMP_COLOR_FORMAT, 0);
 197 
 198         switch (params->clamping_level) {
 199         case CLAMPING_FULL_RANGE:
 200                 REG_UPDATE_2(FMT_CLAMP_CNTL,
 201                                 FMT_CLAMP_DATA_EN, 1,
 202                                 FMT_CLAMP_COLOR_FORMAT, 0);
 203                 break;
 204         case CLAMPING_LIMITED_RANGE_8BPC:
 205                 REG_UPDATE_2(FMT_CLAMP_CNTL,
 206                                 FMT_CLAMP_DATA_EN, 1,
 207                                 FMT_CLAMP_COLOR_FORMAT, 1);
 208                 break;
 209         case CLAMPING_LIMITED_RANGE_10BPC:
 210                 REG_UPDATE_2(FMT_CLAMP_CNTL,
 211                                 FMT_CLAMP_DATA_EN, 1,
 212                                 FMT_CLAMP_COLOR_FORMAT, 2);
 213 
 214                 break;
 215         case CLAMPING_LIMITED_RANGE_12BPC:
 216                 REG_UPDATE_2(FMT_CLAMP_CNTL,
 217                                 FMT_CLAMP_DATA_EN, 1,
 218                                 FMT_CLAMP_COLOR_FORMAT, 3);
 219                 break;
 220         case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
 221                 
 222         default:
 223                 break;
 224         }
 225 
 226 }
 227 
 228 void opp1_set_dyn_expansion(
 229         struct output_pixel_processor *opp,
 230         enum dc_color_space color_sp,
 231         enum dc_color_depth color_dpth,
 232         enum signal_type signal)
 233 {
 234         struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
 235 
 236         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
 237                         FMT_DYNAMIC_EXP_EN, 0,
 238                         FMT_DYNAMIC_EXP_MODE, 0);
 239 
 240         
 241         
 242         if (signal == SIGNAL_TYPE_HDMI_TYPE_A ||
 243                 signal == SIGNAL_TYPE_DISPLAY_PORT ||
 244                 signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
 245                 signal == SIGNAL_TYPE_VIRTUAL) {
 246                 switch (color_dpth) {
 247                 case COLOR_DEPTH_888:
 248                         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
 249                                 FMT_DYNAMIC_EXP_EN, 1,
 250                                 FMT_DYNAMIC_EXP_MODE, 1);
 251                         break;
 252                 case COLOR_DEPTH_101010:
 253                         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
 254                                 FMT_DYNAMIC_EXP_EN, 1,
 255                                 FMT_DYNAMIC_EXP_MODE, 0);
 256                         break;
 257                 case COLOR_DEPTH_121212:
 258                         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
 259                                 FMT_DYNAMIC_EXP_EN, 1,
 260                                 FMT_DYNAMIC_EXP_MODE, 0);
 261                         break;
 262                 default:
 263                         break;
 264                 }
 265         }
 266 }
 267 
 268 static void opp1_program_clamping_and_pixel_encoding(
 269         struct output_pixel_processor *opp,
 270         const struct clamping_and_pixel_encoding_params *params)
 271 {
 272         struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
 273 
 274         opp1_set_clamping(oppn10, params);
 275         opp1_set_pixel_encoding(oppn10, params);
 276 }
 277 
 278 void opp1_program_fmt(
 279         struct output_pixel_processor *opp,
 280         struct bit_depth_reduction_params *fmt_bit_depth,
 281         struct clamping_and_pixel_encoding_params *clamping)
 282 {
 283         struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
 284 
 285         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
 286                 REG_UPDATE(FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, 0);
 287 
 288         
 289 
 290         opp1_program_bit_depth_reduction(
 291                 opp,
 292                 fmt_bit_depth);
 293 
 294         opp1_program_clamping_and_pixel_encoding(
 295                 opp,
 296                 clamping);
 297 
 298         return;
 299 }
 300 
 301 void opp1_program_stereo(
 302         struct output_pixel_processor *opp,
 303         bool enable,
 304         const struct dc_crtc_timing *timing)
 305 {
 306         struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
 307 
 308         uint32_t active_width = timing->h_addressable - timing->h_border_right - timing->h_border_right;
 309         uint32_t space1_size = timing->v_total - timing->v_addressable;
 310         
 311         uint32_t space2_size = timing->v_total - timing->v_addressable;
 312 
 313         if (!enable) {
 314                 active_width = 0;
 315                 space1_size = 0;
 316                 space2_size = 0;
 317         }
 318 
 319         
 320         REG_UPDATE(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, 0);
 321 
 322         REG_UPDATE(OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, active_width);
 323 
 324         
 325 
 326 
 327 
 328 
 329         if (timing->timing_3d_format == TIMING_3D_FORMAT_FRAME_ALTERNATE)
 330                 REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, space2_size);
 331         else
 332                 REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, space1_size);
 333 
 334         
 335         
 336 
 337 
 338 
 339 
 340 
 341 
 342 
 343 }
 344 
 345 void opp1_program_oppbuf(
 346         struct output_pixel_processor *opp,
 347         struct oppbuf_params *oppbuf)
 348 {
 349         struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
 350 
 351         
 352         REG_UPDATE(OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, oppbuf->active_width);
 353 
 354         
 355 
 356 
 357 
 358 
 359 
 360         REG_UPDATE(OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, oppbuf->mso_segmentation);
 361 
 362         
 363         REG_UPDATE(OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, oppbuf->mso_overlap_pixel_num);
 364 
 365         
 366 
 367 
 368         REG_UPDATE(OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, oppbuf->pixel_repetition);
 369 
 370 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 371         
 372         if (REG(OPPBUF_CONTROL1))
 373                 REG_UPDATE(OPPBUF_CONTROL1, OPPBUF_NUM_SEGMENT_PADDED_PIXELS, oppbuf->num_segment_padded_pixels);
 374 #endif
 375 }
 376 
 377 void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable)
 378 {
 379         struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp);
 380         uint32_t regval = enable ? 1 : 0;
 381 
 382         REG_UPDATE(OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, regval);
 383 }
 384 
 385 
 386 
 387 
 388 
 389 void opp1_destroy(struct output_pixel_processor **opp)
 390 {
 391         kfree(TO_DCN10_OPP(*opp));
 392         *opp = NULL;
 393 }
 394 
 395 static const struct opp_funcs dcn10_opp_funcs = {
 396                 .opp_set_dyn_expansion = opp1_set_dyn_expansion,
 397                 .opp_program_fmt = opp1_program_fmt,
 398                 .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
 399                 .opp_program_stereo = opp1_program_stereo,
 400                 .opp_pipe_clock_control = opp1_pipe_clock_control,
 401 #if defined(CONFIG_DRM_AMD_DC_DCN2_0)
 402                 .opp_set_disp_pattern_generator = NULL,
 403 #endif
 404                 .opp_destroy = opp1_destroy
 405 };
 406 
 407 void dcn10_opp_construct(struct dcn10_opp *oppn10,
 408         struct dc_context *ctx,
 409         uint32_t inst,
 410         const struct dcn10_opp_registers *regs,
 411         const struct dcn10_opp_shift *opp_shift,
 412         const struct dcn10_opp_mask *opp_mask)
 413 {
 414 
 415         oppn10->base.ctx = ctx;
 416         oppn10->base.inst = inst;
 417         oppn10->base.funcs = &dcn10_opp_funcs;
 418 
 419         oppn10->regs = regs;
 420         oppn10->opp_shift = opp_shift;
 421         oppn10->opp_mask = opp_mask;
 422 }