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 CTX \
  40        dpp->base.ctx
  41
  42#undef FN
  43#define FN(reg_name, field_name) \
  44        dpp->tf_shift->field_name, dpp->tf_mask->field_name
  45
  46
  47
  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        default:
 153                BREAK_TO_DEBUGGER();
 154                break;
 155        }
 156}
 157
 158static void dpp20_power_on_blnd_lut(
 159        struct dpp *dpp_base,
 160        bool power_on)
 161{
 162        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 163
 164        REG_SET(CM_MEM_PWR_CTRL, 0,
 165                        BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
 166
 167}
 168
 169static void dpp20_configure_blnd_lut(
 170                struct dpp *dpp_base,
 171                bool is_ram_a)
 172{
 173        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 174
 175        REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
 176                        CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
 177        REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
 178                        CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 179        REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
 180}
 181
 182static void dpp20_program_blnd_pwl(
 183                struct dpp *dpp_base,
 184                const struct pwl_result_data *rgb,
 185                uint32_t num)
 186{
 187        uint32_t i;
 188        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 189
 190        for (i = 0 ; i < num; i++) {
 191                REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
 192                REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
 193                REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
 194
 195                REG_SET(CM_BLNDGAM_LUT_DATA, 0,
 196                                CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
 197                REG_SET(CM_BLNDGAM_LUT_DATA, 0,
 198                                CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
 199                REG_SET(CM_BLNDGAM_LUT_DATA, 0,
 200                                CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
 201
 202        }
 203
 204}
 205
 206static void dcn20_dpp_cm_get_reg_field(
 207                struct dcn20_dpp *dpp,
 208                struct xfer_func_reg *reg)
 209{
 210        reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 211        reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 212        reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 213        reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 214        reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 215        reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 216        reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 217        reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 218
 219        reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
 220        reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
 221        reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
 222        reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
 223        reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
 224        reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
 225        reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
 226        reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
 227        reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
 228        reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
 229        reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 230        reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 231}
 232
 233/*program blnd lut RAM A*/
 234static void dpp20_program_blnd_luta_settings(
 235                struct dpp *dpp_base,
 236                const struct pwl_params *params)
 237{
 238        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 239        struct xfer_func_reg gam_regs;
 240
 241        dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
 242
 243        gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
 244        gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
 245        gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
 246        gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
 247        gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
 248        gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
 249        gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
 250        gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
 251        gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
 252        gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
 253        gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
 254        gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
 255        gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
 256        gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
 257
 258        cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 259}
 260
 261/*program blnd lut RAM B*/
 262static void dpp20_program_blnd_lutb_settings(
 263                struct dpp *dpp_base,
 264                const struct pwl_params *params)
 265{
 266        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 267        struct xfer_func_reg gam_regs;
 268
 269        dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
 270
 271        gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
 272        gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
 273        gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
 274        gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
 275        gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
 276        gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
 277        gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
 278        gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
 279        gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
 280        gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
 281        gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
 282        gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
 283        gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
 284        gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
 285
 286        cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
 287}
 288
 289static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base)
 290{
 291        enum dc_lut_mode mode;
 292        uint32_t state_mode;
 293        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 294
 295        REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK,
 296                                        CM_BLNDGAM_CONFIG_STATUS, &state_mode);
 297
 298                switch (state_mode) {
 299                case 0:
 300                        mode = LUT_BYPASS;
 301                        break;
 302                case 1:
 303                        mode = LUT_RAM_A;
 304                        break;
 305                case 2:
 306                        mode = LUT_RAM_B;
 307                        break;
 308                default:
 309                        mode = LUT_BYPASS;
 310                        break;
 311                }
 312                return mode;
 313}
 314
 315bool dpp20_program_blnd_lut(
 316        struct dpp *dpp_base, const struct pwl_params *params)
 317{
 318        enum dc_lut_mode current_mode;
 319        enum dc_lut_mode next_mode;
 320        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 321
 322        if (params == NULL) {
 323                REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
 324                return false;
 325        }
 326        current_mode = dpp20_get_blndgam_current(dpp_base);
 327        if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 328                next_mode = LUT_RAM_B;
 329        else
 330                next_mode = LUT_RAM_A;
 331
 332        dpp20_power_on_blnd_lut(dpp_base, true);
 333        dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A ? true:false);
 334
 335        if (next_mode == LUT_RAM_A)
 336                dpp20_program_blnd_luta_settings(dpp_base, params);
 337        else
 338                dpp20_program_blnd_lutb_settings(dpp_base, params);
 339
 340        dpp20_program_blnd_pwl(
 341                        dpp_base, params->rgb_resulted, params->hw_points_num);
 342
 343        REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
 344                        next_mode == LUT_RAM_A ? 1:2);
 345
 346        return true;
 347}
 348
 349
 350static void dpp20_program_shaper_lut(
 351                struct dpp *dpp_base,
 352                const struct pwl_result_data *rgb,
 353                uint32_t num)
 354{
 355        uint32_t i, red, green, blue;
 356        uint32_t  red_delta, green_delta, blue_delta;
 357        uint32_t  red_value, green_value, blue_value;
 358
 359        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 360
 361        for (i = 0 ; i < num; i++) {
 362
 363                red   = rgb[i].red_reg;
 364                green = rgb[i].green_reg;
 365                blue  = rgb[i].blue_reg;
 366
 367                red_delta   = rgb[i].delta_red_reg;
 368                green_delta = rgb[i].delta_green_reg;
 369                blue_delta  = rgb[i].delta_blue_reg;
 370
 371                red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
 372                green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
 373                blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
 374
 375                REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
 376                REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
 377                REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
 378        }
 379
 380}
 381
 382static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base)
 383{
 384        enum dc_lut_mode mode;
 385        uint32_t state_mode;
 386        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 387
 388        REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK,
 389                        CM_SHAPER_CONFIG_STATUS, &state_mode);
 390
 391                switch (state_mode) {
 392                case 0:
 393                        mode = LUT_BYPASS;
 394                        break;
 395                case 1:
 396                        mode = LUT_RAM_A;
 397                        break;
 398                case 2:
 399                        mode = LUT_RAM_B;
 400                        break;
 401                default:
 402                        mode = LUT_BYPASS;
 403                        break;
 404                }
 405                return mode;
 406}
 407
 408static void dpp20_configure_shaper_lut(
 409                struct dpp *dpp_base,
 410                bool is_ram_a)
 411{
 412        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 413
 414        REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
 415                        CM_SHAPER_LUT_WRITE_EN_MASK, 7);
 416        REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
 417                        CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 418        REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
 419}
 420
 421/*program shaper RAM A*/
 422
 423static void dpp20_program_shaper_luta_settings(
 424                struct dpp *dpp_base,
 425                const struct pwl_params *params)
 426{
 427        const struct gamma_curve *curve;
 428        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 429
 430        REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
 431                CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 432                CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 433        REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
 434                CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
 435                CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
 436        REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
 437                CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
 438                CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
 439
 440        REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
 441                CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 442                CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 443
 444        REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
 445                CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
 446                CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
 447
 448        REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
 449                CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
 450                CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
 451
 452        curve = params->arr_curve_points;
 453        REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
 454                CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 455                CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 456                CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 457                CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 458
 459        curve += 2;
 460        REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
 461                CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
 462                CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
 463                CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
 464                CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
 465
 466        curve += 2;
 467        REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
 468                CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
 469                CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
 470                CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
 471                CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
 472
 473        curve += 2;
 474        REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
 475                CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
 476                CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
 477                CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
 478                CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
 479
 480        curve += 2;
 481        REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
 482                CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
 483                CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
 484                CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
 485                CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
 486
 487        curve += 2;
 488        REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
 489                CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
 490                CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
 491                CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
 492                CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
 493
 494        curve += 2;
 495        REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
 496                CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
 497                CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
 498                CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
 499                CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
 500
 501        curve += 2;
 502        REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
 503                CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
 504                CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
 505                CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
 506                CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
 507
 508        curve += 2;
 509        REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
 510                CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
 511                CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
 512                CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
 513                CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
 514
 515        curve += 2;
 516        REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
 517                CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
 518                CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
 519                CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
 520                CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
 521
 522        curve += 2;
 523        REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
 524                CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
 525                CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
 526                CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
 527                CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
 528
 529        curve += 2;
 530        REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
 531                CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
 532                CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
 533                CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
 534                CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
 535
 536        curve += 2;
 537        REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
 538                CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
 539                CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
 540                CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
 541                CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
 542
 543        curve += 2;
 544        REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
 545                CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
 546                CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
 547                CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
 548                CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
 549
 550        curve += 2;
 551        REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
 552                CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
 553                CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
 554                CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
 555                CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
 556
 557        curve += 2;
 558        REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
 559                CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
 560                CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
 561                CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
 562                CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
 563
 564        curve += 2;
 565        REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
 566                CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
 567                CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
 568                CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
 569                CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
 570}
 571
 572/*program shaper RAM B*/
 573static void dpp20_program_shaper_lutb_settings(
 574                struct dpp *dpp_base,
 575                const struct pwl_params *params)
 576{
 577        const struct gamma_curve *curve;
 578        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 579
 580        REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
 581                CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 582                CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
 583        REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
 584                CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
 585                CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
 586        REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
 587                CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
 588                CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
 589
 590        REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
 591                CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 592                CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 593
 594        REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
 595                CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
 596                CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
 597
 598        REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
 599                CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
 600                CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
 601
 602        curve = params->arr_curve_points;
 603        REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
 604                CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 605                CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 606                CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 607                CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 608
 609        curve += 2;
 610        REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
 611                CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
 612                CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
 613                CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
 614                CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
 615
 616        curve += 2;
 617        REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
 618                CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
 619                CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
 620                CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
 621                CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
 622
 623        curve += 2;
 624        REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
 625                CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
 626                CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
 627                CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
 628                CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
 629
 630        curve += 2;
 631        REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
 632                CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
 633                CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
 634                CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
 635                CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
 636
 637        curve += 2;
 638        REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
 639                CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
 640                CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
 641                CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
 642                CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
 643
 644        curve += 2;
 645        REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
 646                CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
 647                CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
 648                CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
 649                CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
 650
 651        curve += 2;
 652        REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
 653                CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
 654                CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
 655                CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
 656                CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
 657
 658        curve += 2;
 659        REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
 660                CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
 661                CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
 662                CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
 663                CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
 664
 665        curve += 2;
 666        REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
 667                CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
 668                CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
 669                CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
 670                CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
 671
 672        curve += 2;
 673        REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
 674                CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
 675                CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
 676                CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
 677                CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
 678
 679        curve += 2;
 680        REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
 681                CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
 682                CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
 683                CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
 684                CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
 685
 686        curve += 2;
 687        REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
 688                CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
 689                CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
 690                CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
 691                CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
 692
 693        curve += 2;
 694        REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
 695                CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
 696                CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
 697                CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
 698                CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
 699
 700        curve += 2;
 701        REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
 702                CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
 703                CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
 704                CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
 705                CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
 706
 707        curve += 2;
 708        REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
 709                CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
 710                CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
 711                CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
 712                CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
 713
 714        curve += 2;
 715        REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
 716                CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
 717                CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
 718                CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
 719                CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
 720
 721}
 722
 723
 724bool dpp20_program_shaper(
 725                struct dpp *dpp_base,
 726                const struct pwl_params *params)
 727{
 728        enum dc_lut_mode current_mode;
 729        enum dc_lut_mode next_mode;
 730
 731        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 732
 733        if (params == NULL) {
 734                REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
 735                return false;
 736        }
 737        current_mode = dpp20_get_shaper_current(dpp_base);
 738
 739        if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 740                next_mode = LUT_RAM_B;
 741        else
 742                next_mode = LUT_RAM_A;
 743
 744        dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A ? true:false);
 745
 746        if (next_mode == LUT_RAM_A)
 747                dpp20_program_shaper_luta_settings(dpp_base, params);
 748        else
 749                dpp20_program_shaper_lutb_settings(dpp_base, params);
 750
 751        dpp20_program_shaper_lut(
 752                        dpp_base, params->rgb_resulted, params->hw_points_num);
 753
 754        REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
 755
 756        return true;
 757
 758}
 759
 760static enum dc_lut_mode get3dlut_config(
 761                        struct dpp *dpp_base,
 762                        bool *is_17x17x17,
 763                        bool *is_12bits_color_channel)
 764{
 765        uint32_t i_mode, i_enable_10bits, lut_size;
 766        enum dc_lut_mode mode;
 767        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 768
 769        REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL,
 770                        CM_3DLUT_CONFIG_STATUS, &i_mode,
 771                        CM_3DLUT_30BIT_EN, &i_enable_10bits);
 772
 773        switch (i_mode) {
 774        case 0:
 775                mode = LUT_BYPASS;
 776                break;
 777        case 1:
 778                mode = LUT_RAM_A;
 779                break;
 780        case 2:
 781                mode = LUT_RAM_B;
 782                break;
 783        default:
 784                mode = LUT_BYPASS;
 785                break;
 786        }
 787        if (i_enable_10bits > 0)
 788                *is_12bits_color_channel = false;
 789        else
 790                *is_12bits_color_channel = true;
 791
 792        REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
 793
 794        if (lut_size == 0)
 795                *is_17x17x17 = true;
 796        else
 797                *is_17x17x17 = false;
 798
 799        return mode;
 800}
 801/*
 802 * select ramA or ramB, or bypass
 803 * select color channel size 10 or 12 bits
 804 * select 3dlut size 17x17x17 or 9x9x9
 805 */
 806static void dpp20_set_3dlut_mode(
 807                struct dpp *dpp_base,
 808                enum dc_lut_mode mode,
 809                bool is_color_channel_12bits,
 810                bool is_lut_size17x17x17)
 811{
 812        uint32_t lut_mode;
 813        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 814
 815        if (mode == LUT_BYPASS)
 816                lut_mode = 0;
 817        else if (mode == LUT_RAM_A)
 818                lut_mode = 1;
 819        else
 820                lut_mode = 2;
 821
 822        REG_UPDATE_2(CM_3DLUT_MODE,
 823                        CM_3DLUT_MODE, lut_mode,
 824                        CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
 825}
 826
 827static void dpp20_select_3dlut_ram(
 828                struct dpp *dpp_base,
 829                enum dc_lut_mode mode,
 830                bool is_color_channel_12bits)
 831{
 832        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 833
 834        REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
 835                        CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
 836                        CM_3DLUT_30BIT_EN,
 837                        is_color_channel_12bits == true ? 0:1);
 838}
 839
 840
 841
 842static void dpp20_set3dlut_ram12(
 843                struct dpp *dpp_base,
 844                const struct dc_rgb *lut,
 845                uint32_t entries)
 846{
 847        uint32_t i, red, green, blue, red1, green1, blue1;
 848        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 849
 850        for (i = 0 ; i < entries; i += 2) {
 851                red   = lut[i].red<<4;
 852                green = lut[i].green<<4;
 853                blue  = lut[i].blue<<4;
 854                red1   = lut[i+1].red<<4;
 855                green1 = lut[i+1].green<<4;
 856                blue1  = lut[i+1].blue<<4;
 857
 858                REG_SET_2(CM_3DLUT_DATA, 0,
 859                                CM_3DLUT_DATA0, red,
 860                                CM_3DLUT_DATA1, red1);
 861
 862                REG_SET_2(CM_3DLUT_DATA, 0,
 863                                CM_3DLUT_DATA0, green,
 864                                CM_3DLUT_DATA1, green1);
 865
 866                REG_SET_2(CM_3DLUT_DATA, 0,
 867                                CM_3DLUT_DATA0, blue,
 868                                CM_3DLUT_DATA1, blue1);
 869
 870        }
 871}
 872
 873/*
 874 * load selected lut with 10 bits color channels
 875 */
 876static void dpp20_set3dlut_ram10(
 877                struct dpp *dpp_base,
 878                const struct dc_rgb *lut,
 879                uint32_t entries)
 880{
 881        uint32_t i, red, green, blue, value;
 882        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 883
 884        for (i = 0; i < entries; i++) {
 885                red   = lut[i].red;
 886                green = lut[i].green;
 887                blue  = lut[i].blue;
 888
 889                value = (red<<20) | (green<<10) | blue;
 890
 891                REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
 892        }
 893
 894}
 895
 896
 897static void dpp20_select_3dlut_ram_mask(
 898                struct dpp *dpp_base,
 899                uint32_t ram_selection_mask)
 900{
 901        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 902
 903        REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
 904                        ram_selection_mask);
 905        REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
 906}
 907
 908bool dpp20_program_3dlut(
 909                struct dpp *dpp_base,
 910                struct tetrahedral_params *params)
 911{
 912        enum dc_lut_mode mode;
 913        bool is_17x17x17;
 914        bool is_12bits_color_channel;
 915        struct dc_rgb *lut0;
 916        struct dc_rgb *lut1;
 917        struct dc_rgb *lut2;
 918        struct dc_rgb *lut3;
 919        int lut_size0;
 920        int lut_size;
 921
 922        if (params == NULL) {
 923                dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
 924                return false;
 925        }
 926        mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
 927
 928        if (mode == LUT_BYPASS || mode == LUT_RAM_B)
 929                mode = LUT_RAM_A;
 930        else
 931                mode = LUT_RAM_B;
 932
 933        is_17x17x17 = !params->use_tetrahedral_9;
 934        is_12bits_color_channel = params->use_12bits;
 935        if (is_17x17x17) {
 936                lut0 = params->tetrahedral_17.lut0;
 937                lut1 = params->tetrahedral_17.lut1;
 938                lut2 = params->tetrahedral_17.lut2;
 939                lut3 = params->tetrahedral_17.lut3;
 940                lut_size0 = sizeof(params->tetrahedral_17.lut0)/
 941                                        sizeof(params->tetrahedral_17.lut0[0]);
 942                lut_size  = sizeof(params->tetrahedral_17.lut1)/
 943                                        sizeof(params->tetrahedral_17.lut1[0]);
 944        } else {
 945                lut0 = params->tetrahedral_9.lut0;
 946                lut1 = params->tetrahedral_9.lut1;
 947                lut2 = params->tetrahedral_9.lut2;
 948                lut3 = params->tetrahedral_9.lut3;
 949                lut_size0 = sizeof(params->tetrahedral_9.lut0)/
 950                                sizeof(params->tetrahedral_9.lut0[0]);
 951                lut_size  = sizeof(params->tetrahedral_9.lut1)/
 952                                sizeof(params->tetrahedral_9.lut1[0]);
 953                }
 954
 955        dpp20_select_3dlut_ram(dpp_base, mode,
 956                                is_12bits_color_channel);
 957        dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
 958        if (is_12bits_color_channel)
 959                dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
 960        else
 961                dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
 962
 963        dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
 964        if (is_12bits_color_channel)
 965                dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
 966        else
 967                dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
 968
 969        dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
 970        if (is_12bits_color_channel)
 971                dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
 972        else
 973                dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
 974
 975        dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
 976        if (is_12bits_color_channel)
 977                dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
 978        else
 979                dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
 980
 981
 982        dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
 983                                        is_17x17x17);
 984
 985        return true;
 986}
 987
 988void dpp2_set_hdr_multiplier(
 989                struct dpp *dpp_base,
 990                uint32_t multiplier)
 991{
 992        struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
 993
 994        REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
 995}
 996