linux/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp_cm.c
<<
>>
Prefs
   1/*
   2 * Copyright 2016 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
  28#include "core_types.h"
  29
  30#include "reg_helper.h"
  31#include "dcn20_dpp.h"
  32#include "basics/conversion.h"
  33
  34#include "dcn10/dcn10_cm_common.h"
  35
  36#define REG(reg)\
  37        dpp->tf_regs->reg
  38
  39#define IND_REG(index) \
  40        (index)
  41
  42#define CTX \
  43        dpp->base.ctx
  44
  45#undef FN
  46#define FN(reg_name, field_name) \
  47        dpp->tf_shift->field_name, dpp->tf_mask->field_name
  48
  49
  50static void dpp2_enable_cm_block(
  51                struct dpp *dpp_base)
  52{
  53        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
  54
  55        unsigned int cm_bypass_mode = 0;
  56        //Temp, put CM in bypass mode
  57        if (dpp_base->ctx->dc->debug.cm_in_bypass)
  58                cm_bypass_mode = 1;
  59
  60        REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode);
  61}
  62
  63
  64static bool dpp2_degamma_ram_inuse(
  65                struct dpp *dpp_base,
  66                bool *ram_a_inuse)
  67{
  68        bool ret = false;
  69        uint32_t status_reg = 0;
  70        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
  71
  72        REG_GET(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_CONFIG_STATUS,
  73                        &status_reg);
  74
  75        if (status_reg == 3) {
  76                *ram_a_inuse = true;
  77                ret = true;
  78        } else if (status_reg == 4) {
  79                *ram_a_inuse = false;
  80                ret = true;
  81        }
  82        return ret;
  83}
  84
  85static void dpp2_program_degamma_lut(
  86                struct dpp *dpp_base,
  87                const struct pwl_result_data *rgb,
  88                uint32_t num,
  89                bool is_ram_a)
  90{
  91        uint32_t i;
  92
  93        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
  94        REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
  95                                CM_DGAM_LUT_WRITE_EN_MASK, 7);
  96        REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL,
  97                                        is_ram_a == true ? 0:1);
  98
  99        REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0);
 100        for (i = 0 ; i < num; i++) {
 101                REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg);
 102                REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg);
 103                REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg);
 104
 105                REG_SET(CM_DGAM_LUT_DATA, 0,
 106                                CM_DGAM_LUT_DATA, rgb[i].delta_red_reg);
 107                REG_SET(CM_DGAM_LUT_DATA, 0,
 108                                CM_DGAM_LUT_DATA, rgb[i].delta_green_reg);
 109                REG_SET(CM_DGAM_LUT_DATA, 0,
 110                                CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg);
 111
 112        }
 113
 114}
 115
 116void dpp2_set_degamma_pwl(
 117                struct dpp *dpp_base,
 118                const struct pwl_params *params)
 119{
 120        bool is_ram_a = true;
 121
 122        dpp1_power_on_degamma_lut(dpp_base, true);
 123        dpp2_enable_cm_block(dpp_base);
 124        dpp2_degamma_ram_inuse(dpp_base, &is_ram_a);
 125        if (is_ram_a == true)
 126                dpp1_program_degamma_lutb_settings(dpp_base, params);
 127        else
 128                dpp1_program_degamma_luta_settings(dpp_base, params);
 129
 130        dpp2_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a);
 131        dpp1_degamma_ram_select(dpp_base, !is_ram_a);
 132}
 133
 134void dpp2_set_degamma(
 135                struct dpp *dpp_base,
 136                enum ipp_degamma_mode mode)
 137{
 138        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 139        dpp2_enable_cm_block(dpp_base);
 140
 141        switch (mode) {
 142        case IPP_DEGAMMA_MODE_BYPASS:
 143                /* Setting de gamma bypass for now */
 144                REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0);
 145                break;
 146        case IPP_DEGAMMA_MODE_HW_sRGB:
 147                REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1);
 148                break;
 149        case IPP_DEGAMMA_MODE_HW_xvYCC:
 150                REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2);
 151                        break;
 152        case IPP_DEGAMMA_MODE_USER_PWL:
 153                REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
 154                break;
 155        default:
 156                BREAK_TO_DEBUGGER();
 157                break;
 158        }
 159}
 160
 161static void program_gamut_remap(
 162                struct dcn20_dpp *dpp,
 163                const uint16_t *regval,
 164                enum dcn20_gamut_remap_select select)
 165{
 166        uint32_t cur_select = 0;
 167        struct color_matrices_reg gam_regs;
 168
 169        if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) {
 170                REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
 171                                CM_GAMUT_REMAP_MODE, 0);
 172                return;
 173        }
 174
 175        /* determine which gamut_remap coefficients (A or B) we are using
 176         * currently. select the alternate set to double buffer
 177         * the update so gamut_remap is updated on frame boundary
 178         */
 179        IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
 180                                        CM_TEST_DEBUG_DATA_STATUS_IDX,
 181                                        CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select);
 182
 183        /* value stored in dbg reg will be 1 greater than mode we want */
 184        if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
 185                select = DCN2_GAMUT_REMAP_COEF_A;
 186        else
 187                select = DCN2_GAMUT_REMAP_COEF_B;
 188
 189        gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
 190        gam_regs.masks.csc_c11  = dpp->tf_mask->CM_GAMUT_REMAP_C11;
 191        gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
 192        gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
 193
 194        if (select == DCN2_GAMUT_REMAP_COEF_A) {
 195                gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12);
 196                gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
 197        } else {
 198                gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12);
 199                gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34);
 200        }
 201
 202        cm_helper_program_color_matrices(
 203                                dpp->base.ctx,
 204                                regval,
 205                                &gam_regs);
 206
 207        REG_SET(
 208                        CM_GAMUT_REMAP_CONTROL, 0,
 209                        CM_GAMUT_REMAP_MODE, select);
 210
 211}
 212
 213void dpp2_cm_set_gamut_remap(
 214        struct dpp *dpp_base,
 215        const struct dpp_grph_csc_adjustment *adjust)
 216{
 217        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 218        int i = 0;
 219
 220        if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
 221                /* Bypass if type is bypass or hw */
 222                program_gamut_remap(dpp, NULL, DCN2_GAMUT_REMAP_BYPASS);
 223        else {
 224                struct fixed31_32 arr_matrix[12];
 225                uint16_t arr_reg_val[12];
 226
 227                for (i = 0; i < 12; i++)
 228                        arr_matrix[i] = adjust->temperature_matrix[i];
 229
 230                convert_float_matrix(
 231                        arr_reg_val, arr_matrix, 12);
 232
 233                program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A);
 234        }
 235}
 236
 237void dpp2_program_input_csc(
 238                struct dpp *dpp_base,
 239                enum dc_color_space color_space,
 240                enum dcn20_input_csc_select input_select,
 241                const struct out_csc_color_matrix *tbl_entry)
 242{
 243        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 244        int i;
 245        int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
 246        const uint16_t *regval = NULL;
 247        uint32_t cur_select = 0;
 248        enum dcn20_input_csc_select select;
 249        struct color_matrices_reg icsc_regs;
 250
 251        if (input_select == DCN2_ICSC_SELECT_BYPASS) {
 252                REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
 253                return;
 254        }
 255
 256        if (tbl_entry == NULL) {
 257                for (i = 0; i < arr_size; i++)
 258                        if (dpp_input_csc_matrix[i].color_space == color_space) {
 259                                regval = dpp_input_csc_matrix[i].regval;
 260                                break;
 261                        }
 262
 263                if (regval == NULL) {
 264                        BREAK_TO_DEBUGGER();
 265                        return;
 266                }
 267        } else {
 268                regval = tbl_entry->regval;
 269        }
 270
 271        /* determine which CSC coefficients (A or B) we are using
 272         * currently.  select the alternate set to double buffer
 273         * the CSC update so CSC is updated on frame boundary
 274         */
 275        IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
 276                                        CM_TEST_DEBUG_DATA_STATUS_IDX,
 277                                        CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);
 278
 279        if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
 280                select = DCN2_ICSC_SELECT_ICSC_A;
 281        else
 282                select = DCN2_ICSC_SELECT_ICSC_B;
 283
 284        icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
 285        icsc_regs.masks.csc_c11  = dpp->tf_mask->CM_ICSC_C11;
 286        icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
 287        icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
 288
 289        if (select == DCN2_ICSC_SELECT_ICSC_A) {
 290
 291                icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
 292                icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
 293
 294        } else {
 295
 296                icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
 297                icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
 298
 299        }
 300
 301        cm_helper_program_color_matrices(
 302                        dpp->base.ctx,
 303                        regval,
 304                        &icsc_regs);
 305
 306        REG_SET(CM_ICSC_CONTROL, 0,
 307                                CM_ICSC_MODE, select);
 308}
 309
 310static void dpp20_power_on_blnd_lut(
 311        struct dpp *dpp_base,
 312        bool power_on)
 313{
 314        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 315
 316        REG_SET(CM_MEM_PWR_CTRL, 0,
 317                        BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
 318
 319}
 320
 321static void dpp20_configure_blnd_lut(
 322                struct dpp *dpp_base,
 323                bool is_ram_a)
 324{
 325        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 326
 327        REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
 328                        CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
 329        REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
 330                        CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 331        REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
 332}
 333
 334static void dpp20_program_blnd_pwl(
 335                struct dpp *dpp_base,
 336                const struct pwl_result_data *rgb,
 337                uint32_t num)
 338{
 339        uint32_t i;
 340        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 341
 342        for (i = 0 ; i < num; i++) {
 343                REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
 344                REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
 345                REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
 346
 347                REG_SET(CM_BLNDGAM_LUT_DATA, 0,
 348                                CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
 349                REG_SET(CM_BLNDGAM_LUT_DATA, 0,
 350                                CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
 351                REG_SET(CM_BLNDGAM_LUT_DATA, 0,
 352                                CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
 353
 354        }
 355
 356}
 357
 358static void dcn20_dpp_cm_get_reg_field(
 359                struct dcn20_dpp *dpp,
 360                struct xfer_func_reg *reg)
 361{
 362        reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 363        reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 364        reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 365        reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 366        reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 367        reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 368        reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 369        reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 370
 371        reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
 372        reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
 373        reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
 374        reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
 375        reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
 376        reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
 377        reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
 378        reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
 379        reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
 380        reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
 381        reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 382        reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 383}
 384
 385/*program blnd lut RAM A*/
 386static void dpp20_program_blnd_luta_settings(
 387                struct dpp *dpp_base,
 388                const struct pwl_params *params)
 389{
 390        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 391        struct xfer_func_reg gam_regs;
 392
 393        dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
 394
 395        gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
 396        gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
 397        gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
 398        gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
 399        gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
 400        gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
 401        gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
 402        gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
 403        gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
 404        gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
 405        gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
 406        gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
 407        gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
 408        gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
 409
 410        cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 411}
 412
 413/*program blnd lut RAM B*/
 414static void dpp20_program_blnd_lutb_settings(
 415                struct dpp *dpp_base,
 416                const struct pwl_params *params)
 417{
 418        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 419        struct xfer_func_reg gam_regs;
 420
 421        dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
 422
 423        gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
 424        gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
 425        gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
 426        gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
 427        gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
 428        gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
 429        gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
 430        gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
 431        gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
 432        gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
 433        gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
 434        gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
 435        gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
 436        gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
 437
 438        cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 439}
 440
 441static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base)
 442{
 443        enum dc_lut_mode mode;
 444        uint32_t state_mode;
 445        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 446
 447        REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK,
 448                                        CM_BLNDGAM_CONFIG_STATUS, &state_mode);
 449
 450                switch (state_mode) {
 451                case 0:
 452                        mode = LUT_BYPASS;
 453                        break;
 454                case 1:
 455                        mode = LUT_RAM_A;
 456                        break;
 457                case 2:
 458                        mode = LUT_RAM_B;
 459                        break;
 460                default:
 461                        mode = LUT_BYPASS;
 462                        break;
 463                }
 464                return mode;
 465}
 466
 467bool dpp20_program_blnd_lut(
 468        struct dpp *dpp_base, const struct pwl_params *params)
 469{
 470        enum dc_lut_mode current_mode;
 471        enum dc_lut_mode next_mode;
 472        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 473
 474        if (params == NULL) {
 475                REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
 476                return false;
 477        }
 478        current_mode = dpp20_get_blndgam_current(dpp_base);
 479        if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 480                next_mode = LUT_RAM_B;
 481        else
 482                next_mode = LUT_RAM_A;
 483
 484        dpp20_power_on_blnd_lut(dpp_base, true);
 485        dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
 486
 487        if (next_mode == LUT_RAM_A)
 488                dpp20_program_blnd_luta_settings(dpp_base, params);
 489        else
 490                dpp20_program_blnd_lutb_settings(dpp_base, params);
 491
 492        dpp20_program_blnd_pwl(
 493                        dpp_base, params->rgb_resulted, params->hw_points_num);
 494
 495        REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
 496                        next_mode == LUT_RAM_A ? 1:2);
 497
 498        return true;
 499}
 500
 501
 502static void dpp20_program_shaper_lut(
 503                struct dpp *dpp_base,
 504                const struct pwl_result_data *rgb,
 505                uint32_t num)
 506{
 507        uint32_t i, red, green, blue;
 508        uint32_t  red_delta, green_delta, blue_delta;
 509        uint32_t  red_value, green_value, blue_value;
 510
 511        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 512
 513        for (i = 0 ; i < num; i++) {
 514
 515                red   = rgb[i].red_reg;
 516                green = rgb[i].green_reg;
 517                blue  = rgb[i].blue_reg;
 518
 519                red_delta   = rgb[i].delta_red_reg;
 520                green_delta = rgb[i].delta_green_reg;
 521                blue_delta  = rgb[i].delta_blue_reg;
 522
 523                red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
 524                green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
 525                blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
 526
 527                REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
 528                REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
 529                REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
 530        }
 531
 532}
 533
 534static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base)
 535{
 536        enum dc_lut_mode mode;
 537        uint32_t state_mode;
 538        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 539
 540        REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK,
 541                        CM_SHAPER_CONFIG_STATUS, &state_mode);
 542
 543                switch (state_mode) {
 544                case 0:
 545                        mode = LUT_BYPASS;
 546                        break;
 547                case 1:
 548                        mode = LUT_RAM_A;
 549                        break;
 550                case 2:
 551                        mode = LUT_RAM_B;
 552                        break;
 553                default:
 554                        mode = LUT_BYPASS;
 555                        break;
 556                }
 557                return mode;
 558}
 559
 560static void dpp20_configure_shaper_lut(
 561                struct dpp *dpp_base,
 562                bool is_ram_a)
 563{
 564        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 565
 566        REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
 567                        CM_SHAPER_LUT_WRITE_EN_MASK, 7);
 568        REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
 569                        CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 570        REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
 571}
 572
 573/*program shaper RAM A*/
 574
 575static void dpp20_program_shaper_luta_settings(
 576                struct dpp *dpp_base,
 577                const struct pwl_params *params)
 578{
 579        const struct gamma_curve *curve;
 580        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 581
 582        REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
 583                CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 584                CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 585        REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
 586                CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
 587                CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
 588        REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
 589                CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
 590                CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
 591
 592        REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
 593                CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 594                CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 595
 596        REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
 597                CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
 598                CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
 599
 600        REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
 601                CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
 602                CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
 603
 604        curve = params->arr_curve_points;
 605        REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
 606                CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 607                CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 608                CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 609                CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 610
 611        curve += 2;
 612        REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
 613                CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
 614                CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
 615                CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
 616                CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
 617
 618        curve += 2;
 619        REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
 620                CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
 621                CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
 622                CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
 623                CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
 624
 625        curve += 2;
 626        REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
 627                CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
 628                CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
 629                CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
 630                CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
 631
 632        curve += 2;
 633        REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
 634                CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
 635                CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
 636                CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
 637                CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
 638
 639        curve += 2;
 640        REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
 641                CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
 642                CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
 643                CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
 644                CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
 645
 646        curve += 2;
 647        REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
 648                CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
 649                CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
 650                CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
 651                CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
 652
 653        curve += 2;
 654        REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
 655                CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
 656                CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
 657                CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
 658                CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
 659
 660        curve += 2;
 661        REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
 662                CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
 663                CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
 664                CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
 665                CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
 666
 667        curve += 2;
 668        REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
 669                CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
 670                CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
 671                CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
 672                CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
 673
 674        curve += 2;
 675        REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
 676                CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
 677                CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
 678                CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
 679                CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
 680
 681        curve += 2;
 682        REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
 683                CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
 684                CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
 685                CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
 686                CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
 687
 688        curve += 2;
 689        REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
 690                CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
 691                CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
 692                CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
 693                CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
 694
 695        curve += 2;
 696        REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
 697                CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
 698                CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
 699                CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
 700                CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
 701
 702        curve += 2;
 703        REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
 704                CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
 705                CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
 706                CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
 707                CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
 708
 709        curve += 2;
 710        REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
 711                CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
 712                CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
 713                CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
 714                CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
 715
 716        curve += 2;
 717        REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
 718                CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
 719                CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
 720                CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
 721                CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
 722}
 723
 724/*program shaper RAM B*/
 725static void dpp20_program_shaper_lutb_settings(
 726                struct dpp *dpp_base,
 727                const struct pwl_params *params)
 728{
 729        const struct gamma_curve *curve;
 730        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 731
 732        REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
 733                CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 734                CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
 735        REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
 736                CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
 737                CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
 738        REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
 739                CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
 740                CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
 741
 742        REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
 743                CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 744                CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 745
 746        REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
 747                CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
 748                CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
 749
 750        REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
 751                CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
 752                CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
 753
 754        curve = params->arr_curve_points;
 755        REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
 756                CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 757                CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 758                CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 759                CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 760
 761        curve += 2;
 762        REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
 763                CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
 764                CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
 765                CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
 766                CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
 767
 768        curve += 2;
 769        REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
 770                CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
 771                CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
 772                CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
 773                CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
 774
 775        curve += 2;
 776        REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
 777                CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
 778                CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
 779                CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
 780                CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
 781
 782        curve += 2;
 783        REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
 784                CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
 785                CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
 786                CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
 787                CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
 788
 789        curve += 2;
 790        REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
 791                CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
 792                CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
 793                CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
 794                CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
 795
 796        curve += 2;
 797        REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
 798                CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
 799                CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
 800                CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
 801                CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
 802
 803        curve += 2;
 804        REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
 805                CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
 806                CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
 807                CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
 808                CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
 809
 810        curve += 2;
 811        REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
 812                CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
 813                CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
 814                CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
 815                CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
 816
 817        curve += 2;
 818        REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
 819                CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
 820                CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
 821                CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
 822                CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
 823
 824        curve += 2;
 825        REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
 826                CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
 827                CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
 828                CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
 829                CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
 830
 831        curve += 2;
 832        REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
 833                CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
 834                CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
 835                CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
 836                CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
 837
 838        curve += 2;
 839        REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
 840                CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
 841                CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
 842                CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
 843                CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
 844
 845        curve += 2;
 846        REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
 847                CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
 848                CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
 849                CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
 850                CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
 851
 852        curve += 2;
 853        REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
 854                CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
 855                CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
 856                CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
 857                CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
 858
 859        curve += 2;
 860        REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
 861                CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
 862                CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
 863                CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
 864                CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
 865
 866        curve += 2;
 867        REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
 868                CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
 869                CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
 870                CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
 871                CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
 872
 873}
 874
 875
 876bool dpp20_program_shaper(
 877                struct dpp *dpp_base,
 878                const struct pwl_params *params)
 879{
 880        enum dc_lut_mode current_mode;
 881        enum dc_lut_mode next_mode;
 882
 883        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 884
 885        if (params == NULL) {
 886                REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
 887                return false;
 888        }
 889        current_mode = dpp20_get_shaper_current(dpp_base);
 890
 891        if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 892                next_mode = LUT_RAM_B;
 893        else
 894                next_mode = LUT_RAM_A;
 895
 896        dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
 897
 898        if (next_mode == LUT_RAM_A)
 899                dpp20_program_shaper_luta_settings(dpp_base, params);
 900        else
 901                dpp20_program_shaper_lutb_settings(dpp_base, params);
 902
 903        dpp20_program_shaper_lut(
 904                        dpp_base, params->rgb_resulted, params->hw_points_num);
 905
 906        REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
 907
 908        return true;
 909
 910}
 911
 912static enum dc_lut_mode get3dlut_config(
 913                        struct dpp *dpp_base,
 914                        bool *is_17x17x17,
 915                        bool *is_12bits_color_channel)
 916{
 917        uint32_t i_mode, i_enable_10bits, lut_size;
 918        enum dc_lut_mode mode;
 919        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 920
 921        REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL,
 922                        CM_3DLUT_CONFIG_STATUS, &i_mode,
 923                        CM_3DLUT_30BIT_EN, &i_enable_10bits);
 924
 925        switch (i_mode) {
 926        case 0:
 927                mode = LUT_BYPASS;
 928                break;
 929        case 1:
 930                mode = LUT_RAM_A;
 931                break;
 932        case 2:
 933                mode = LUT_RAM_B;
 934                break;
 935        default:
 936                mode = LUT_BYPASS;
 937                break;
 938        }
 939        if (i_enable_10bits > 0)
 940                *is_12bits_color_channel = false;
 941        else
 942                *is_12bits_color_channel = true;
 943
 944        REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
 945
 946        if (lut_size == 0)
 947                *is_17x17x17 = true;
 948        else
 949                *is_17x17x17 = false;
 950
 951        return mode;
 952}
 953/*
 954 * select ramA or ramB, or bypass
 955 * select color channel size 10 or 12 bits
 956 * select 3dlut size 17x17x17 or 9x9x9
 957 */
 958static void dpp20_set_3dlut_mode(
 959                struct dpp *dpp_base,
 960                enum dc_lut_mode mode,
 961                bool is_color_channel_12bits,
 962                bool is_lut_size17x17x17)
 963{
 964        uint32_t lut_mode;
 965        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 966
 967        if (mode == LUT_BYPASS)
 968                lut_mode = 0;
 969        else if (mode == LUT_RAM_A)
 970                lut_mode = 1;
 971        else
 972                lut_mode = 2;
 973
 974        REG_UPDATE_2(CM_3DLUT_MODE,
 975                        CM_3DLUT_MODE, lut_mode,
 976                        CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
 977}
 978
 979static void dpp20_select_3dlut_ram(
 980                struct dpp *dpp_base,
 981                enum dc_lut_mode mode,
 982                bool is_color_channel_12bits)
 983{
 984        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 985
 986        REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
 987                        CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
 988                        CM_3DLUT_30BIT_EN,
 989                        is_color_channel_12bits == true ? 0:1);
 990}
 991
 992
 993
 994static void dpp20_set3dlut_ram12(
 995                struct dpp *dpp_base,
 996                const struct dc_rgb *lut,
 997                uint32_t entries)
 998{
 999        uint32_t i, red, green, blue, red1, green1, blue1;
1000        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1001
1002        for (i = 0 ; i < entries; i += 2) {
1003                red   = lut[i].red<<4;
1004                green = lut[i].green<<4;
1005                blue  = lut[i].blue<<4;
1006                red1   = lut[i+1].red<<4;
1007                green1 = lut[i+1].green<<4;
1008                blue1  = lut[i+1].blue<<4;
1009
1010                REG_SET_2(CM_3DLUT_DATA, 0,
1011                                CM_3DLUT_DATA0, red,
1012                                CM_3DLUT_DATA1, red1);
1013
1014                REG_SET_2(CM_3DLUT_DATA, 0,
1015                                CM_3DLUT_DATA0, green,
1016                                CM_3DLUT_DATA1, green1);
1017
1018                REG_SET_2(CM_3DLUT_DATA, 0,
1019                                CM_3DLUT_DATA0, blue,
1020                                CM_3DLUT_DATA1, blue1);
1021
1022        }
1023}
1024
1025/*
1026 * load selected lut with 10 bits color channels
1027 */
1028static void dpp20_set3dlut_ram10(
1029                struct dpp *dpp_base,
1030                const struct dc_rgb *lut,
1031                uint32_t entries)
1032{
1033        uint32_t i, red, green, blue, value;
1034        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1035
1036        for (i = 0; i < entries; i++) {
1037                red   = lut[i].red;
1038                green = lut[i].green;
1039                blue  = lut[i].blue;
1040
1041                value = (red<<20) | (green<<10) | blue;
1042
1043                REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
1044        }
1045
1046}
1047
1048
1049static void dpp20_select_3dlut_ram_mask(
1050                struct dpp *dpp_base,
1051                uint32_t ram_selection_mask)
1052{
1053        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1054
1055        REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
1056                        ram_selection_mask);
1057        REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
1058}
1059
1060bool dpp20_program_3dlut(
1061                struct dpp *dpp_base,
1062                struct tetrahedral_params *params)
1063{
1064        enum dc_lut_mode mode;
1065        bool is_17x17x17;
1066        bool is_12bits_color_channel;
1067        struct dc_rgb *lut0;
1068        struct dc_rgb *lut1;
1069        struct dc_rgb *lut2;
1070        struct dc_rgb *lut3;
1071        int lut_size0;
1072        int lut_size;
1073
1074        if (params == NULL) {
1075                dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
1076                return false;
1077        }
1078        mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
1079
1080        if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1081                mode = LUT_RAM_A;
1082        else
1083                mode = LUT_RAM_B;
1084
1085        is_17x17x17 = !params->use_tetrahedral_9;
1086        is_12bits_color_channel = params->use_12bits;
1087        if (is_17x17x17) {
1088                lut0 = params->tetrahedral_17.lut0;
1089                lut1 = params->tetrahedral_17.lut1;
1090                lut2 = params->tetrahedral_17.lut2;
1091                lut3 = params->tetrahedral_17.lut3;
1092                lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1093                                        sizeof(params->tetrahedral_17.lut0[0]);
1094                lut_size  = sizeof(params->tetrahedral_17.lut1)/
1095                                        sizeof(params->tetrahedral_17.lut1[0]);
1096        } else {
1097                lut0 = params->tetrahedral_9.lut0;
1098                lut1 = params->tetrahedral_9.lut1;
1099                lut2 = params->tetrahedral_9.lut2;
1100                lut3 = params->tetrahedral_9.lut3;
1101                lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1102                                sizeof(params->tetrahedral_9.lut0[0]);
1103                lut_size  = sizeof(params->tetrahedral_9.lut1)/
1104                                sizeof(params->tetrahedral_9.lut1[0]);
1105                }
1106
1107        dpp20_select_3dlut_ram(dpp_base, mode,
1108                                is_12bits_color_channel);
1109        dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
1110        if (is_12bits_color_channel)
1111                dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
1112        else
1113                dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
1114
1115        dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
1116        if (is_12bits_color_channel)
1117                dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
1118        else
1119                dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
1120
1121        dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
1122        if (is_12bits_color_channel)
1123                dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
1124        else
1125                dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
1126
1127        dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
1128        if (is_12bits_color_channel)
1129                dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
1130        else
1131                dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
1132
1133
1134        dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
1135                                        is_17x17x17);
1136
1137        return true;
1138}
1139
1140void dpp2_set_hdr_multiplier(
1141                struct dpp *dpp_base,
1142                uint32_t multiplier)
1143{
1144        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1145
1146        REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
1147}
1148