root/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_regamma_v.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. power_on_lut
  2. set_bypass_input_gamma
  3. configure_regamma_mode
  4. regamma_config_regions_and_segments
  5. program_pwl
  6. dce110_opp_program_regamma_pwl_v
  7. dce110_opp_power_on_regamma_lut_v
  8. dce110_opp_set_regamma_mode_v

   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 <linux/delay.h>
  27 
  28 #include "dm_services.h"
  29 
  30 /* include DCE11 register header files */
  31 #include "dce/dce_11_0_d.h"
  32 #include "dce/dce_11_0_sh_mask.h"
  33 
  34 #include "dce110_transform_v.h"
  35 
  36 static void power_on_lut(struct transform *xfm,
  37         bool power_on, bool inputgamma, bool regamma)
  38 {
  39         uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
  40         int i;
  41 
  42         if (power_on) {
  43                 if (inputgamma)
  44                         set_reg_field_value(
  45                                 value,
  46                                 1,
  47                                 DCFEV_MEM_PWR_CTRL,
  48                                 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
  49                 if (regamma)
  50                         set_reg_field_value(
  51                                 value,
  52                                 1,
  53                                 DCFEV_MEM_PWR_CTRL,
  54                                 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
  55         } else {
  56                 if (inputgamma)
  57                         set_reg_field_value(
  58                                 value,
  59                                 0,
  60                                 DCFEV_MEM_PWR_CTRL,
  61                                 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
  62                 if (regamma)
  63                         set_reg_field_value(
  64                                 value,
  65                                 0,
  66                                 DCFEV_MEM_PWR_CTRL,
  67                                 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
  68         }
  69 
  70         dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
  71 
  72         for (i = 0; i < 3; i++) {
  73                 value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
  74                 if (get_reg_field_value(value,
  75                                 DCFEV_MEM_PWR_CTRL,
  76                                 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) &&
  77                         get_reg_field_value(value,
  78                                         DCFEV_MEM_PWR_CTRL,
  79                                         COL_MAN_GAMMA_CORR_MEM_PWR_DIS))
  80                         break;
  81 
  82                 udelay(2);
  83         }
  84 }
  85 
  86 static void set_bypass_input_gamma(struct dce_transform *xfm_dce)
  87 {
  88         uint32_t value;
  89 
  90         value = dm_read_reg(xfm_dce->base.ctx,
  91                         mmCOL_MAN_INPUT_GAMMA_CONTROL1);
  92 
  93         set_reg_field_value(
  94                                 value,
  95                                 0,
  96                                 COL_MAN_INPUT_GAMMA_CONTROL1,
  97                                 INPUT_GAMMA_MODE);
  98 
  99         dm_write_reg(xfm_dce->base.ctx,
 100                         mmCOL_MAN_INPUT_GAMMA_CONTROL1, value);
 101 }
 102 
 103 static void configure_regamma_mode(struct dce_transform *xfm_dce, uint32_t mode)
 104 {
 105         uint32_t value = 0;
 106 
 107         set_reg_field_value(
 108                                 value,
 109                                 mode,
 110                                 GAMMA_CORR_CONTROL,
 111                                 GAMMA_CORR_MODE);
 112 
 113         dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CONTROL, 0);
 114 }
 115 
 116 /*
 117  *****************************************************************************
 118  *  Function: regamma_config_regions_and_segments
 119  *
 120  *     build regamma curve by using predefined hw points
 121  *     uses interface parameters ,like EDID coeff.
 122  *
 123  * @param   : parameters   interface parameters
 124  *  @return void
 125  *
 126  *  @note
 127  *
 128  *  @see
 129  *
 130  *****************************************************************************
 131  */
 132 static void regamma_config_regions_and_segments(
 133         struct dce_transform *xfm_dce, const struct pwl_params *params)
 134 {
 135         const struct gamma_curve *curve;
 136         uint32_t value = 0;
 137 
 138         {
 139                 set_reg_field_value(
 140                         value,
 141                         params->arr_points[0].custom_float_x,
 142                         GAMMA_CORR_CNTLA_START_CNTL,
 143                         GAMMA_CORR_CNTLA_EXP_REGION_START);
 144 
 145                 set_reg_field_value(
 146                         value,
 147                         0,
 148                         GAMMA_CORR_CNTLA_START_CNTL,
 149                         GAMMA_CORR_CNTLA_EXP_REGION_START_SEGMENT);
 150 
 151                 dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CNTLA_START_CNTL,
 152                                 value);
 153         }
 154         {
 155                 value = 0;
 156                 set_reg_field_value(
 157                         value,
 158                         params->arr_points[0].custom_float_slope,
 159                         GAMMA_CORR_CNTLA_SLOPE_CNTL,
 160                         GAMMA_CORR_CNTLA_EXP_REGION_LINEAR_SLOPE);
 161 
 162                 dm_write_reg(xfm_dce->base.ctx,
 163                         mmGAMMA_CORR_CNTLA_SLOPE_CNTL, value);
 164         }
 165         {
 166                 value = 0;
 167                 set_reg_field_value(
 168                         value,
 169                         params->arr_points[1].custom_float_x,
 170                         GAMMA_CORR_CNTLA_END_CNTL1,
 171                         GAMMA_CORR_CNTLA_EXP_REGION_END);
 172 
 173                 dm_write_reg(xfm_dce->base.ctx,
 174                         mmGAMMA_CORR_CNTLA_END_CNTL1, value);
 175         }
 176         {
 177                 value = 0;
 178                 set_reg_field_value(
 179                         value,
 180                         params->arr_points[1].custom_float_slope,
 181                         GAMMA_CORR_CNTLA_END_CNTL2,
 182                         GAMMA_CORR_CNTLA_EXP_REGION_END_BASE);
 183 
 184                 set_reg_field_value(
 185                         value,
 186                         params->arr_points[1].custom_float_y,
 187                         GAMMA_CORR_CNTLA_END_CNTL2,
 188                         GAMMA_CORR_CNTLA_EXP_REGION_END_SLOPE);
 189 
 190                 dm_write_reg(xfm_dce->base.ctx,
 191                         mmGAMMA_CORR_CNTLA_END_CNTL2, value);
 192         }
 193 
 194         curve = params->arr_curve_points;
 195 
 196         {
 197                 value = 0;
 198                 set_reg_field_value(
 199                         value,
 200                         curve[0].offset,
 201                         GAMMA_CORR_CNTLA_REGION_0_1,
 202                         GAMMA_CORR_CNTLA_EXP_REGION0_LUT_OFFSET);
 203 
 204                 set_reg_field_value(
 205                         value,
 206                         curve[0].segments_num,
 207                         GAMMA_CORR_CNTLA_REGION_0_1,
 208                         GAMMA_CORR_CNTLA_EXP_REGION0_NUM_SEGMENTS);
 209 
 210                 set_reg_field_value(
 211                         value,
 212                         curve[1].offset,
 213                         GAMMA_CORR_CNTLA_REGION_0_1,
 214                         GAMMA_CORR_CNTLA_EXP_REGION1_LUT_OFFSET);
 215 
 216                 set_reg_field_value(
 217                         value,
 218                         curve[1].segments_num,
 219                         GAMMA_CORR_CNTLA_REGION_0_1,
 220                         GAMMA_CORR_CNTLA_EXP_REGION1_NUM_SEGMENTS);
 221 
 222                 dm_write_reg(
 223                                 xfm_dce->base.ctx,
 224                         mmGAMMA_CORR_CNTLA_REGION_0_1,
 225                         value);
 226         }
 227 
 228         curve += 2;
 229         {
 230                 value = 0;
 231                 set_reg_field_value(
 232                         value,
 233                         curve[0].offset,
 234                         GAMMA_CORR_CNTLA_REGION_2_3,
 235                         GAMMA_CORR_CNTLA_EXP_REGION2_LUT_OFFSET);
 236 
 237                 set_reg_field_value(
 238                         value,
 239                         curve[0].segments_num,
 240                         GAMMA_CORR_CNTLA_REGION_2_3,
 241                         GAMMA_CORR_CNTLA_EXP_REGION2_NUM_SEGMENTS);
 242 
 243                 set_reg_field_value(
 244                         value,
 245                         curve[1].offset,
 246                         GAMMA_CORR_CNTLA_REGION_2_3,
 247                         GAMMA_CORR_CNTLA_EXP_REGION3_LUT_OFFSET);
 248 
 249                 set_reg_field_value(
 250                         value,
 251                         curve[1].segments_num,
 252                         GAMMA_CORR_CNTLA_REGION_2_3,
 253                         GAMMA_CORR_CNTLA_EXP_REGION3_NUM_SEGMENTS);
 254 
 255                 dm_write_reg(xfm_dce->base.ctx,
 256                         mmGAMMA_CORR_CNTLA_REGION_2_3,
 257                         value);
 258         }
 259 
 260         curve += 2;
 261         {
 262                 value = 0;
 263                 set_reg_field_value(
 264                         value,
 265                         curve[0].offset,
 266                         GAMMA_CORR_CNTLA_REGION_4_5,
 267                         GAMMA_CORR_CNTLA_EXP_REGION4_LUT_OFFSET);
 268 
 269                 set_reg_field_value(
 270                         value,
 271                         curve[0].segments_num,
 272                         GAMMA_CORR_CNTLA_REGION_4_5,
 273                         GAMMA_CORR_CNTLA_EXP_REGION4_NUM_SEGMENTS);
 274 
 275                 set_reg_field_value(
 276                         value,
 277                         curve[1].offset,
 278                         GAMMA_CORR_CNTLA_REGION_4_5,
 279                         GAMMA_CORR_CNTLA_EXP_REGION5_LUT_OFFSET);
 280 
 281                 set_reg_field_value(
 282                         value,
 283                         curve[1].segments_num,
 284                         GAMMA_CORR_CNTLA_REGION_4_5,
 285                         GAMMA_CORR_CNTLA_EXP_REGION5_NUM_SEGMENTS);
 286 
 287                 dm_write_reg(xfm_dce->base.ctx,
 288                         mmGAMMA_CORR_CNTLA_REGION_4_5,
 289                         value);
 290         }
 291 
 292         curve += 2;
 293         {
 294                 value = 0;
 295                 set_reg_field_value(
 296                         value,
 297                         curve[0].offset,
 298                         GAMMA_CORR_CNTLA_REGION_6_7,
 299                         GAMMA_CORR_CNTLA_EXP_REGION6_LUT_OFFSET);
 300 
 301                 set_reg_field_value(
 302                         value,
 303                         curve[0].segments_num,
 304                         GAMMA_CORR_CNTLA_REGION_6_7,
 305                         GAMMA_CORR_CNTLA_EXP_REGION6_NUM_SEGMENTS);
 306 
 307                 set_reg_field_value(
 308                         value,
 309                         curve[1].offset,
 310                         GAMMA_CORR_CNTLA_REGION_6_7,
 311                         GAMMA_CORR_CNTLA_EXP_REGION7_LUT_OFFSET);
 312 
 313                 set_reg_field_value(
 314                         value,
 315                         curve[1].segments_num,
 316                         GAMMA_CORR_CNTLA_REGION_6_7,
 317                         GAMMA_CORR_CNTLA_EXP_REGION7_NUM_SEGMENTS);
 318 
 319                 dm_write_reg(xfm_dce->base.ctx,
 320                         mmGAMMA_CORR_CNTLA_REGION_6_7,
 321                         value);
 322         }
 323 
 324         curve += 2;
 325         {
 326                 value = 0;
 327                 set_reg_field_value(
 328                         value,
 329                         curve[0].offset,
 330                         GAMMA_CORR_CNTLA_REGION_8_9,
 331                         GAMMA_CORR_CNTLA_EXP_REGION8_LUT_OFFSET);
 332 
 333                 set_reg_field_value(
 334                         value,
 335                         curve[0].segments_num,
 336                         GAMMA_CORR_CNTLA_REGION_8_9,
 337                         GAMMA_CORR_CNTLA_EXP_REGION8_NUM_SEGMENTS);
 338 
 339                 set_reg_field_value(
 340                         value,
 341                         curve[1].offset,
 342                         GAMMA_CORR_CNTLA_REGION_8_9,
 343                         GAMMA_CORR_CNTLA_EXP_REGION9_LUT_OFFSET);
 344 
 345                 set_reg_field_value(
 346                         value,
 347                         curve[1].segments_num,
 348                         GAMMA_CORR_CNTLA_REGION_8_9,
 349                         GAMMA_CORR_CNTLA_EXP_REGION9_NUM_SEGMENTS);
 350 
 351                 dm_write_reg(xfm_dce->base.ctx,
 352                         mmGAMMA_CORR_CNTLA_REGION_8_9,
 353                         value);
 354         }
 355 
 356         curve += 2;
 357         {
 358                 value = 0;
 359                 set_reg_field_value(
 360                         value,
 361                         curve[0].offset,
 362                         GAMMA_CORR_CNTLA_REGION_10_11,
 363                         GAMMA_CORR_CNTLA_EXP_REGION10_LUT_OFFSET);
 364 
 365                 set_reg_field_value(
 366                         value,
 367                         curve[0].segments_num,
 368                         GAMMA_CORR_CNTLA_REGION_10_11,
 369                         GAMMA_CORR_CNTLA_EXP_REGION10_NUM_SEGMENTS);
 370 
 371                 set_reg_field_value(
 372                         value,
 373                         curve[1].offset,
 374                         GAMMA_CORR_CNTLA_REGION_10_11,
 375                         GAMMA_CORR_CNTLA_EXP_REGION11_LUT_OFFSET);
 376 
 377                 set_reg_field_value(
 378                         value,
 379                         curve[1].segments_num,
 380                         GAMMA_CORR_CNTLA_REGION_10_11,
 381                         GAMMA_CORR_CNTLA_EXP_REGION11_NUM_SEGMENTS);
 382 
 383                 dm_write_reg(xfm_dce->base.ctx,
 384                         mmGAMMA_CORR_CNTLA_REGION_10_11,
 385                         value);
 386         }
 387 
 388         curve += 2;
 389         {
 390                 value = 0;
 391                 set_reg_field_value(
 392                         value,
 393                         curve[0].offset,
 394                         GAMMA_CORR_CNTLA_REGION_12_13,
 395                         GAMMA_CORR_CNTLA_EXP_REGION12_LUT_OFFSET);
 396 
 397                 set_reg_field_value(
 398                         value,
 399                         curve[0].segments_num,
 400                         GAMMA_CORR_CNTLA_REGION_12_13,
 401                         GAMMA_CORR_CNTLA_EXP_REGION12_NUM_SEGMENTS);
 402 
 403                 set_reg_field_value(
 404                         value,
 405                         curve[1].offset,
 406                         GAMMA_CORR_CNTLA_REGION_12_13,
 407                         GAMMA_CORR_CNTLA_EXP_REGION13_LUT_OFFSET);
 408 
 409                 set_reg_field_value(
 410                         value,
 411                         curve[1].segments_num,
 412                         GAMMA_CORR_CNTLA_REGION_12_13,
 413                         GAMMA_CORR_CNTLA_EXP_REGION13_NUM_SEGMENTS);
 414 
 415                 dm_write_reg(xfm_dce->base.ctx,
 416                         mmGAMMA_CORR_CNTLA_REGION_12_13,
 417                         value);
 418         }
 419 
 420         curve += 2;
 421         {
 422                 value = 0;
 423                 set_reg_field_value(
 424                         value,
 425                         curve[0].offset,
 426                         GAMMA_CORR_CNTLA_REGION_14_15,
 427                         GAMMA_CORR_CNTLA_EXP_REGION14_LUT_OFFSET);
 428 
 429                 set_reg_field_value(
 430                         value,
 431                         curve[0].segments_num,
 432                         GAMMA_CORR_CNTLA_REGION_14_15,
 433                         GAMMA_CORR_CNTLA_EXP_REGION14_NUM_SEGMENTS);
 434 
 435                 set_reg_field_value(
 436                         value,
 437                         curve[1].offset,
 438                         GAMMA_CORR_CNTLA_REGION_14_15,
 439                         GAMMA_CORR_CNTLA_EXP_REGION15_LUT_OFFSET);
 440 
 441                 set_reg_field_value(
 442                         value,
 443                         curve[1].segments_num,
 444                         GAMMA_CORR_CNTLA_REGION_14_15,
 445                         GAMMA_CORR_CNTLA_EXP_REGION15_NUM_SEGMENTS);
 446 
 447                 dm_write_reg(xfm_dce->base.ctx,
 448                         mmGAMMA_CORR_CNTLA_REGION_14_15,
 449                         value);
 450         }
 451 }
 452 
 453 static void program_pwl(struct dce_transform *xfm_dce,
 454                 const struct pwl_params *params)
 455 {
 456         uint32_t value = 0;
 457 
 458         set_reg_field_value(
 459                 value,
 460                 7,
 461                 GAMMA_CORR_LUT_WRITE_EN_MASK,
 462                 GAMMA_CORR_LUT_WRITE_EN_MASK);
 463 
 464         dm_write_reg(xfm_dce->base.ctx,
 465                 mmGAMMA_CORR_LUT_WRITE_EN_MASK, value);
 466 
 467         dm_write_reg(xfm_dce->base.ctx,
 468                 mmGAMMA_CORR_LUT_INDEX, 0);
 469 
 470         /* Program REGAMMA_LUT_DATA */
 471         {
 472                 const uint32_t addr = mmGAMMA_CORR_LUT_DATA;
 473                 uint32_t i = 0;
 474                 const struct pwl_result_data *rgb =
 475                                 params->rgb_resulted;
 476 
 477                 while (i != params->hw_points_num) {
 478                         dm_write_reg(xfm_dce->base.ctx, addr, rgb->red_reg);
 479                         dm_write_reg(xfm_dce->base.ctx, addr, rgb->green_reg);
 480                         dm_write_reg(xfm_dce->base.ctx, addr, rgb->blue_reg);
 481 
 482                         dm_write_reg(xfm_dce->base.ctx, addr,
 483                                 rgb->delta_red_reg);
 484                         dm_write_reg(xfm_dce->base.ctx, addr,
 485                                 rgb->delta_green_reg);
 486                         dm_write_reg(xfm_dce->base.ctx, addr,
 487                                 rgb->delta_blue_reg);
 488 
 489                         ++rgb;
 490                         ++i;
 491                 }
 492         }
 493 }
 494 
 495 void dce110_opp_program_regamma_pwl_v(
 496         struct transform *xfm,
 497         const struct pwl_params *params)
 498 {
 499         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
 500 
 501         /* Setup regions */
 502         regamma_config_regions_and_segments(xfm_dce, params);
 503 
 504         set_bypass_input_gamma(xfm_dce);
 505 
 506         /* Power on gamma LUT memory */
 507         power_on_lut(xfm, true, false, true);
 508 
 509         /* Program PWL */
 510         program_pwl(xfm_dce, params);
 511 
 512         /* program regamma config */
 513         configure_regamma_mode(xfm_dce, 1);
 514 
 515         /* Power return to auto back */
 516         power_on_lut(xfm, false, false, true);
 517 }
 518 
 519 void dce110_opp_power_on_regamma_lut_v(
 520         struct transform *xfm,
 521         bool power_on)
 522 {
 523         uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
 524 
 525         set_reg_field_value(
 526                 value,
 527                 0,
 528                 DCFEV_MEM_PWR_CTRL,
 529                 COL_MAN_GAMMA_CORR_MEM_PWR_FORCE);
 530 
 531         set_reg_field_value(
 532                 value,
 533                 power_on,
 534                 DCFEV_MEM_PWR_CTRL,
 535                 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
 536 
 537         set_reg_field_value(
 538                 value,
 539                 0,
 540                 DCFEV_MEM_PWR_CTRL,
 541                 COL_MAN_INPUT_GAMMA_MEM_PWR_FORCE);
 542 
 543         set_reg_field_value(
 544                 value,
 545                 power_on,
 546                 DCFEV_MEM_PWR_CTRL,
 547                 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
 548 
 549         dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
 550 }
 551 
 552 void dce110_opp_set_regamma_mode_v(
 553         struct transform *xfm,
 554         enum opp_regamma mode)
 555 {
 556         // TODO: need to implement the function
 557 }

/* [<][>][^][v][top][bottom][index][help] */