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