linux/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
<<
>>
Prefs
   1/*
   2 * Copyright 2020 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 "reg_helper.h"
  27#include "dcn30_mpc.h"
  28#include "dcn30_cm_common.h"
  29#include "basics/conversion.h"
  30#include "dcn10/dcn10_cm_common.h"
  31#include "dc.h"
  32
  33#define REG(reg)\
  34        mpc30->mpc_regs->reg
  35
  36#define CTX \
  37        mpc30->base.ctx
  38
  39#undef FN
  40#define FN(reg_name, field_name) \
  41        mpc30->mpc_shift->field_name, mpc30->mpc_mask->field_name
  42
  43
  44#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
  45
  46
  47static bool mpc3_is_dwb_idle(
  48        struct mpc *mpc,
  49        int dwb_id)
  50{
  51        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  52        unsigned int status;
  53
  54        REG_GET(DWB_MUX[dwb_id], MPC_DWB0_MUX_STATUS, &status);
  55
  56        if (status == 0xf)
  57                return true;
  58        else
  59                return false;
  60}
  61
  62static void mpc3_set_dwb_mux(
  63        struct mpc *mpc,
  64        int dwb_id,
  65        int mpcc_id)
  66{
  67        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  68
  69        REG_SET(DWB_MUX[dwb_id], 0,
  70                MPC_DWB0_MUX, mpcc_id);
  71}
  72
  73static void mpc3_disable_dwb_mux(
  74        struct mpc *mpc,
  75        int dwb_id)
  76{
  77        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  78
  79        REG_SET(DWB_MUX[dwb_id], 0,
  80                MPC_DWB0_MUX, 0xf);
  81}
  82
  83static void mpc3_set_out_rate_control(
  84        struct mpc *mpc,
  85        int opp_id,
  86        bool enable,
  87        bool rate_2x_mode,
  88        struct mpc_dwb_flow_control *flow_control)
  89{
  90        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  91
  92        REG_UPDATE_2(MUX[opp_id],
  93                        MPC_OUT_RATE_CONTROL_DISABLE, !enable,
  94                        MPC_OUT_RATE_CONTROL, rate_2x_mode);
  95
  96        if (flow_control)
  97                REG_UPDATE_2(MUX[opp_id],
  98                        MPC_OUT_FLOW_CONTROL_MODE, flow_control->flow_ctrl_mode,
  99                        MPC_OUT_FLOW_CONTROL_COUNT, flow_control->flow_ctrl_cnt1);
 100}
 101
 102static enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
 103{
 104        /*Contrary to DCN2 and DCN1 wherein a single status register field holds this info;
 105         *in DCN3/3AG, we need to read two separate fields to retrieve the same info
 106         */
 107        enum dc_lut_mode mode;
 108        uint32_t state_mode;
 109        uint32_t state_ram_lut_in_use;
 110        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 111
 112        REG_GET_2(MPCC_OGAM_CONTROL[mpcc_id],
 113                        MPCC_OGAM_MODE_CURRENT, &state_mode,
 114                        MPCC_OGAM_SELECT_CURRENT, &state_ram_lut_in_use);
 115
 116                switch (state_mode) {
 117                case 0:
 118                        mode = LUT_BYPASS;
 119                        break;
 120                case 2:
 121                        switch (state_ram_lut_in_use) {
 122                        case 0:
 123                                mode = LUT_RAM_A;
 124                                break;
 125                        case 1:
 126                                mode = LUT_RAM_B;
 127                                break;
 128                        default:
 129                                mode = LUT_BYPASS;
 130                                break;
 131                        }
 132                        break;
 133                default:
 134                        mode = LUT_BYPASS;
 135                        break;
 136                }
 137                return mode;
 138}
 139
 140static void mpc3_power_on_ogam_lut(
 141                struct mpc *mpc, int mpcc_id,
 142                bool power_on)
 143{
 144        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 145
 146        REG_SET(MPCC_MEM_PWR_CTRL[mpcc_id], 0,
 147                        MPCC_OGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
 148}
 149
 150static void mpc3_configure_ogam_lut(
 151                struct mpc *mpc, int mpcc_id,
 152                bool is_ram_a)
 153{
 154        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 155
 156        REG_UPDATE_2(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 157                        MPCC_OGAM_LUT_WRITE_COLOR_MASK, 7,
 158                        MPCC_OGAM_LUT_HOST_SEL, is_ram_a == true ? 0:1);
 159
 160        REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 161}
 162
 163static void mpc3_ogam_get_reg_field(
 164                struct mpc *mpc,
 165                struct dcn3_xfer_func_reg *reg)
 166{
 167        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 168
 169        reg->shifts.field_region_start_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B;
 170        reg->masks.field_region_start_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B;
 171        reg->shifts.field_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_OFFSET_B;
 172        reg->masks.field_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_OFFSET_B;
 173
 174        reg->shifts.exp_region0_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 175        reg->masks.exp_region0_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 176        reg->shifts.exp_region0_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 177        reg->masks.exp_region0_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 178        reg->shifts.exp_region1_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 179        reg->masks.exp_region1_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 180        reg->shifts.exp_region1_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 181        reg->masks.exp_region1_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 182
 183        reg->shifts.field_region_end = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_B;
 184        reg->masks.field_region_end = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_B;
 185        reg->shifts.field_region_end_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B;
 186        reg->masks.field_region_end_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B;
 187        reg->shifts.field_region_end_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B;
 188        reg->masks.field_region_end_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B;
 189        reg->shifts.field_region_linear_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B;
 190        reg->masks.field_region_linear_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B;
 191        reg->shifts.exp_region_start = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_B;
 192        reg->masks.exp_region_start = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_B;
 193        reg->shifts.exp_resion_start_segment = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 194        reg->masks.exp_resion_start_segment = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 195}
 196
 197static void mpc3_program_luta(struct mpc *mpc, int mpcc_id,
 198                const struct pwl_params *params)
 199{
 200        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 201        struct dcn3_xfer_func_reg gam_regs;
 202
 203        mpc3_ogam_get_reg_field(mpc, &gam_regs);
 204
 205        gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMA_START_CNTL_B[mpcc_id]);
 206        gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMA_START_CNTL_G[mpcc_id]);
 207        gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMA_START_CNTL_R[mpcc_id]);
 208        gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_B[mpcc_id]);
 209        gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_G[mpcc_id]);
 210        gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_R[mpcc_id]);
 211        gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMA_END_CNTL1_B[mpcc_id]);
 212        gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMA_END_CNTL2_B[mpcc_id]);
 213        gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMA_END_CNTL1_G[mpcc_id]);
 214        gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMA_END_CNTL2_G[mpcc_id]);
 215        gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMA_END_CNTL1_R[mpcc_id]);
 216        gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMA_END_CNTL2_R[mpcc_id]);
 217        gam_regs.region_start = REG(MPCC_OGAM_RAMA_REGION_0_1[mpcc_id]);
 218        gam_regs.region_end = REG(MPCC_OGAM_RAMA_REGION_32_33[mpcc_id]);
 219        //New registers in DCN3AG/DCN OGAM block
 220        gam_regs.offset_b =  REG(MPCC_OGAM_RAMA_OFFSET_B[mpcc_id]);
 221        gam_regs.offset_g =  REG(MPCC_OGAM_RAMA_OFFSET_G[mpcc_id]);
 222        gam_regs.offset_r =  REG(MPCC_OGAM_RAMA_OFFSET_R[mpcc_id]);
 223        gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_B[mpcc_id]);
 224        gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_G[mpcc_id]);
 225        gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_R[mpcc_id]);
 226
 227        cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs);
 228}
 229
 230static void mpc3_program_lutb(struct mpc *mpc, int mpcc_id,
 231                const struct pwl_params *params)
 232{
 233        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 234        struct dcn3_xfer_func_reg gam_regs;
 235
 236        mpc3_ogam_get_reg_field(mpc, &gam_regs);
 237
 238        gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMB_START_CNTL_B[mpcc_id]);
 239        gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMB_START_CNTL_G[mpcc_id]);
 240        gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMB_START_CNTL_R[mpcc_id]);
 241        gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_B[mpcc_id]);
 242        gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_G[mpcc_id]);
 243        gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_R[mpcc_id]);
 244        gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMB_END_CNTL1_B[mpcc_id]);
 245        gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMB_END_CNTL2_B[mpcc_id]);
 246        gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMB_END_CNTL1_G[mpcc_id]);
 247        gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMB_END_CNTL2_G[mpcc_id]);
 248        gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMB_END_CNTL1_R[mpcc_id]);
 249        gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMB_END_CNTL2_R[mpcc_id]);
 250        gam_regs.region_start = REG(MPCC_OGAM_RAMB_REGION_0_1[mpcc_id]);
 251        gam_regs.region_end = REG(MPCC_OGAM_RAMB_REGION_32_33[mpcc_id]);
 252        //New registers in DCN3AG/DCN OGAM block
 253        gam_regs.offset_b =  REG(MPCC_OGAM_RAMB_OFFSET_B[mpcc_id]);
 254        gam_regs.offset_g =  REG(MPCC_OGAM_RAMB_OFFSET_G[mpcc_id]);
 255        gam_regs.offset_r =  REG(MPCC_OGAM_RAMB_OFFSET_R[mpcc_id]);
 256        gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_B[mpcc_id]);
 257        gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_G[mpcc_id]);
 258        gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_R[mpcc_id]);
 259
 260        cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs);
 261}
 262
 263
 264static void mpc3_program_ogam_pwl(
 265                struct mpc *mpc, int mpcc_id,
 266                const struct pwl_result_data *rgb,
 267                uint32_t num)
 268{
 269        uint32_t i;
 270        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 271        uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg;
 272        uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg;
 273        uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg;
 274
 275        /*the entries of DCN3AG gamma LUTs take 18bit base values as opposed to
 276         *38 base+delta values per entry in earlier DCN architectures
 277         *last base value for our lut is compute by adding the last base value
 278         *in our data + last delta
 279         */
 280
 281        if (is_rgb_equal(rgb,  num)) {
 282                for (i = 0 ; i < num; i++)
 283                        REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
 284
 285                REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red);
 286
 287        } else {
 288
 289                REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 290                                MPCC_OGAM_LUT_WRITE_COLOR_MASK, 4);
 291
 292                for (i = 0 ; i < num; i++)
 293                        REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
 294
 295                REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red);
 296
 297                REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 298
 299                REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 300                                MPCC_OGAM_LUT_WRITE_COLOR_MASK, 2);
 301
 302                for (i = 0 ; i < num; i++)
 303                        REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].green_reg);
 304
 305                REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_green);
 306
 307                REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 308
 309                REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 310                                MPCC_OGAM_LUT_WRITE_COLOR_MASK, 1);
 311
 312                for (i = 0 ; i < num; i++)
 313                        REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].blue_reg);
 314
 315                REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_blue);
 316        }
 317
 318}
 319
 320void mpc3_set_output_gamma(
 321                struct mpc *mpc,
 322                int mpcc_id,
 323                const struct pwl_params *params)
 324{
 325        enum dc_lut_mode current_mode;
 326        enum dc_lut_mode next_mode;
 327        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 328
 329        if (mpc->ctx->dc->debug.cm_in_bypass) {
 330                REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0);
 331                return;
 332        }
 333
 334        if (params == NULL) { //disable OGAM
 335                REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 0);
 336                return;
 337        }
 338        //enable OGAM
 339        REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 2);
 340
 341        current_mode = mpc3_get_ogam_current(mpc, mpcc_id);
 342        if (current_mode == LUT_BYPASS)
 343                next_mode = LUT_RAM_A;
 344        else if (current_mode == LUT_RAM_A)
 345                next_mode = LUT_RAM_B;
 346        else
 347                next_mode = LUT_RAM_A;
 348
 349        mpc3_power_on_ogam_lut(mpc, mpcc_id, true);
 350        mpc3_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A ? true:false);
 351
 352        if (next_mode == LUT_RAM_A)
 353                mpc3_program_luta(mpc, mpcc_id, params);
 354        else
 355                mpc3_program_lutb(mpc, mpcc_id, params);
 356
 357        mpc3_program_ogam_pwl(
 358                        mpc, mpcc_id, params->rgb_resulted, params->hw_points_num);
 359
 360        /*we need to program 2 fields here as apposed to 1*/
 361        REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id],
 362                        MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1);
 363}
 364
 365void mpc3_set_denorm(
 366                struct mpc *mpc,
 367                int opp_id,
 368                enum dc_color_depth output_depth)
 369{
 370        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 371        /* De-normalize Fixed U1.13 color data to different target bit depths. 0 is bypass*/
 372        int denorm_mode = 0;
 373
 374        switch (output_depth) {
 375        case COLOR_DEPTH_666:
 376                denorm_mode = 1;
 377                break;
 378        case COLOR_DEPTH_888:
 379                denorm_mode = 2;
 380                break;
 381        case COLOR_DEPTH_999:
 382                denorm_mode = 3;
 383                break;
 384        case COLOR_DEPTH_101010:
 385                denorm_mode = 4;
 386                break;
 387        case COLOR_DEPTH_111111:
 388                denorm_mode = 5;
 389                break;
 390        case COLOR_DEPTH_121212:
 391                denorm_mode = 6;
 392                break;
 393        case COLOR_DEPTH_141414:
 394        case COLOR_DEPTH_161616:
 395        default:
 396                /* not valid used case! */
 397                break;
 398        }
 399
 400        REG_UPDATE(DENORM_CONTROL[opp_id],
 401                        MPC_OUT_DENORM_MODE, denorm_mode);
 402}
 403
 404void mpc3_set_denorm_clamp(
 405                struct mpc *mpc,
 406                int opp_id,
 407                struct mpc_denorm_clamp denorm_clamp)
 408{
 409        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 410
 411        /*program min and max clamp values for the pixel components*/
 412        REG_UPDATE_2(DENORM_CONTROL[opp_id],
 413                        MPC_OUT_DENORM_CLAMP_MAX_R_CR, denorm_clamp.clamp_max_r_cr,
 414                        MPC_OUT_DENORM_CLAMP_MIN_R_CR, denorm_clamp.clamp_min_r_cr);
 415        REG_UPDATE_2(DENORM_CLAMP_G_Y[opp_id],
 416                        MPC_OUT_DENORM_CLAMP_MAX_G_Y, denorm_clamp.clamp_max_g_y,
 417                        MPC_OUT_DENORM_CLAMP_MIN_G_Y, denorm_clamp.clamp_min_g_y);
 418        REG_UPDATE_2(DENORM_CLAMP_B_CB[opp_id],
 419                        MPC_OUT_DENORM_CLAMP_MAX_B_CB, denorm_clamp.clamp_max_b_cb,
 420                        MPC_OUT_DENORM_CLAMP_MIN_B_CB, denorm_clamp.clamp_min_b_cb);
 421}
 422
 423static enum dc_lut_mode mpc3_get_shaper_current(struct mpc *mpc, uint32_t rmu_idx)
 424{
 425        enum dc_lut_mode mode;
 426        uint32_t state_mode;
 427        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 428
 429        REG_GET(SHAPER_CONTROL[rmu_idx],
 430                        MPC_RMU_SHAPER_LUT_MODE_CURRENT, &state_mode);
 431
 432                switch (state_mode) {
 433                case 0:
 434                        mode = LUT_BYPASS;
 435                        break;
 436                case 1:
 437                        mode = LUT_RAM_A;
 438                        break;
 439                case 2:
 440                        mode = LUT_RAM_B;
 441                        break;
 442                default:
 443                        mode = LUT_BYPASS;
 444                        break;
 445                }
 446                return mode;
 447}
 448
 449static void mpc3_configure_shaper_lut(
 450                struct mpc *mpc,
 451                bool is_ram_a,
 452                uint32_t rmu_idx)
 453{
 454        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 455
 456        REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx],
 457                        MPC_RMU_SHAPER_LUT_WRITE_EN_MASK, 7);
 458        REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx],
 459                        MPC_RMU_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 460        REG_SET(SHAPER_LUT_INDEX[rmu_idx], 0, MPC_RMU_SHAPER_LUT_INDEX, 0);
 461}
 462
 463static void mpc3_program_shaper_luta_settings(
 464                struct mpc *mpc,
 465                const struct pwl_params *params,
 466                uint32_t rmu_idx)
 467{
 468        const struct gamma_curve *curve;
 469        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 470
 471        REG_SET_2(SHAPER_RAMA_START_CNTL_B[rmu_idx], 0,
 472                MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 473                MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 474        REG_SET_2(SHAPER_RAMA_START_CNTL_G[rmu_idx], 0,
 475                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
 476                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 477        REG_SET_2(SHAPER_RAMA_START_CNTL_R[rmu_idx], 0,
 478                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
 479                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 480
 481        REG_SET_2(SHAPER_RAMA_END_CNTL_B[rmu_idx], 0,
 482                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 483                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 484        REG_SET_2(SHAPER_RAMA_END_CNTL_G[rmu_idx], 0,
 485                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
 486                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
 487        REG_SET_2(SHAPER_RAMA_END_CNTL_R[rmu_idx], 0,
 488                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
 489                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
 490
 491        curve = params->arr_curve_points;
 492        REG_SET_4(SHAPER_RAMA_REGION_0_1[rmu_idx], 0,
 493                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 494                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 495                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 496                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 497
 498        curve += 2;
 499        REG_SET_4(SHAPER_RAMA_REGION_2_3[rmu_idx], 0,
 500                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 501                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 502                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 503                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 504
 505        curve += 2;
 506        REG_SET_4(SHAPER_RAMA_REGION_4_5[rmu_idx], 0,
 507                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 508                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 509                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 510                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 511
 512        curve += 2;
 513        REG_SET_4(SHAPER_RAMA_REGION_6_7[rmu_idx], 0,
 514                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 515                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 516                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 517                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 518
 519        curve += 2;
 520        REG_SET_4(SHAPER_RAMA_REGION_8_9[rmu_idx], 0,
 521                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 522                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 523                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 524                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 525
 526        curve += 2;
 527        REG_SET_4(SHAPER_RAMA_REGION_10_11[rmu_idx], 0,
 528                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 529                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 530                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 531                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 532
 533        curve += 2;
 534        REG_SET_4(SHAPER_RAMA_REGION_12_13[rmu_idx], 0,
 535                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 536                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 537                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 538                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 539
 540        curve += 2;
 541        REG_SET_4(SHAPER_RAMA_REGION_14_15[rmu_idx], 0,
 542                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 543                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 544                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 545                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 546
 547
 548        curve += 2;
 549        REG_SET_4(SHAPER_RAMA_REGION_16_17[rmu_idx], 0,
 550                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 551                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 552                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 553                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 554
 555        curve += 2;
 556        REG_SET_4(SHAPER_RAMA_REGION_18_19[rmu_idx], 0,
 557                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 558                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 559                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 560                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 561
 562        curve += 2;
 563        REG_SET_4(SHAPER_RAMA_REGION_20_21[rmu_idx], 0,
 564                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 565                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 566                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 567                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 568
 569        curve += 2;
 570        REG_SET_4(SHAPER_RAMA_REGION_22_23[rmu_idx], 0,
 571                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 572                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 573                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 574                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 575
 576        curve += 2;
 577        REG_SET_4(SHAPER_RAMA_REGION_24_25[rmu_idx], 0,
 578                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 579                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 580                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 581                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 582
 583        curve += 2;
 584        REG_SET_4(SHAPER_RAMA_REGION_26_27[rmu_idx], 0,
 585                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 586                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 587                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 588                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 589
 590        curve += 2;
 591        REG_SET_4(SHAPER_RAMA_REGION_28_29[rmu_idx], 0,
 592                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 593                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 594                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 595                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 596
 597        curve += 2;
 598        REG_SET_4(SHAPER_RAMA_REGION_30_31[rmu_idx], 0,
 599                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 600                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 601                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 602                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 603
 604        curve += 2;
 605        REG_SET_4(SHAPER_RAMA_REGION_32_33[rmu_idx], 0,
 606                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 607                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 608                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 609                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 610}
 611
 612static void mpc3_program_shaper_lutb_settings(
 613                struct mpc *mpc,
 614                const struct pwl_params *params,
 615                uint32_t rmu_idx)
 616{
 617        const struct gamma_curve *curve;
 618        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 619
 620        REG_SET_2(SHAPER_RAMB_START_CNTL_B[rmu_idx], 0,
 621                MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 622                MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 623        REG_SET_2(SHAPER_RAMB_START_CNTL_G[rmu_idx], 0,
 624                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
 625                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 626        REG_SET_2(SHAPER_RAMB_START_CNTL_R[rmu_idx], 0,
 627                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
 628                        MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 629
 630        REG_SET_2(SHAPER_RAMB_END_CNTL_B[rmu_idx], 0,
 631                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 632                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 633        REG_SET_2(SHAPER_RAMB_END_CNTL_G[rmu_idx], 0,
 634                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
 635                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
 636        REG_SET_2(SHAPER_RAMB_END_CNTL_R[rmu_idx], 0,
 637                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
 638                        MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
 639
 640        curve = params->arr_curve_points;
 641        REG_SET_4(SHAPER_RAMB_REGION_0_1[rmu_idx], 0,
 642                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 643                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 644                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 645                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 646
 647        curve += 2;
 648        REG_SET_4(SHAPER_RAMB_REGION_2_3[rmu_idx], 0,
 649                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 650                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 651                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 652                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 653
 654
 655        curve += 2;
 656        REG_SET_4(SHAPER_RAMB_REGION_4_5[rmu_idx], 0,
 657                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 658                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 659                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 660                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 661
 662        curve += 2;
 663        REG_SET_4(SHAPER_RAMB_REGION_6_7[rmu_idx], 0,
 664                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 665                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 666                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 667                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 668
 669        curve += 2;
 670        REG_SET_4(SHAPER_RAMB_REGION_8_9[rmu_idx], 0,
 671                MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 672                MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 673                MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 674                MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 675
 676        curve += 2;
 677        REG_SET_4(SHAPER_RAMB_REGION_10_11[rmu_idx], 0,
 678                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 679                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 680                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 681                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 682
 683        curve += 2;
 684        REG_SET_4(SHAPER_RAMB_REGION_12_13[rmu_idx], 0,
 685                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 686                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 687                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 688                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 689
 690        curve += 2;
 691        REG_SET_4(SHAPER_RAMB_REGION_14_15[rmu_idx], 0,
 692                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 693                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 694                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 695                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 696
 697
 698        curve += 2;
 699        REG_SET_4(SHAPER_RAMB_REGION_16_17[rmu_idx], 0,
 700                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 701                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 702                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 703                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 704
 705        curve += 2;
 706        REG_SET_4(SHAPER_RAMB_REGION_18_19[rmu_idx], 0,
 707                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 708                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 709                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 710                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 711
 712        curve += 2;
 713        REG_SET_4(SHAPER_RAMB_REGION_20_21[rmu_idx], 0,
 714                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 715                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 716                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 717                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 718
 719        curve += 2;
 720        REG_SET_4(SHAPER_RAMB_REGION_22_23[rmu_idx], 0,
 721                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 722                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 723                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 724                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 725
 726        curve += 2;
 727        REG_SET_4(SHAPER_RAMB_REGION_24_25[rmu_idx], 0,
 728                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 729                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 730                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 731                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 732
 733        curve += 2;
 734        REG_SET_4(SHAPER_RAMB_REGION_26_27[rmu_idx], 0,
 735                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 736                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 737                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 738                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 739
 740        curve += 2;
 741        REG_SET_4(SHAPER_RAMB_REGION_28_29[rmu_idx], 0,
 742                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 743                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 744                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 745                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 746
 747        curve += 2;
 748        REG_SET_4(SHAPER_RAMB_REGION_30_31[rmu_idx], 0,
 749                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 750                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 751                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 752                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 753
 754        curve += 2;
 755        REG_SET_4(SHAPER_RAMB_REGION_32_33[rmu_idx], 0,
 756                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 757                        MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 758                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 759                        MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 760}
 761
 762
 763static void mpc3_program_shaper_lut(
 764                struct mpc *mpc,
 765                const struct pwl_result_data *rgb,
 766                uint32_t num,
 767                uint32_t rmu_idx)
 768{
 769        uint32_t i, red, green, blue;
 770        uint32_t  red_delta, green_delta, blue_delta;
 771        uint32_t  red_value, green_value, blue_value;
 772
 773        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 774
 775        for (i = 0 ; i < num; i++) {
 776
 777                red   = rgb[i].red_reg;
 778                green = rgb[i].green_reg;
 779                blue  = rgb[i].blue_reg;
 780
 781                red_delta   = rgb[i].delta_red_reg;
 782                green_delta = rgb[i].delta_green_reg;
 783                blue_delta  = rgb[i].delta_blue_reg;
 784
 785                red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
 786                green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
 787                blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
 788
 789                REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, red_value);
 790                REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, green_value);
 791                REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, blue_value);
 792        }
 793
 794}
 795
 796static void mpc3_power_on_shaper_3dlut(
 797                struct mpc *mpc,
 798                uint32_t rmu_idx,
 799        bool power_on)
 800{
 801        uint32_t power_status_shaper = 2;
 802        uint32_t power_status_3dlut  = 2;
 803        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 804
 805        if (rmu_idx == 0) {
 806                REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
 807                        MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0);
 808                /*read status is not mandatory, it is just for debugging*/
 809                REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper);
 810                REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
 811        } else if (rmu_idx == 1) {
 812                REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
 813                        MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0);
 814                REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper);
 815                REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
 816        }
 817        /*TODO Add rmu_idx == 2 for SIENNA_CICHLID */
 818        if (power_status_shaper != 0 && power_on == true)
 819                BREAK_TO_DEBUGGER();
 820
 821        if (power_status_3dlut != 0 && power_on == true)
 822                BREAK_TO_DEBUGGER();
 823}
 824
 825
 826
 827bool mpc3_program_shaper(
 828                struct mpc *mpc,
 829                const struct pwl_params *params,
 830                uint32_t rmu_idx)
 831{
 832        enum dc_lut_mode current_mode;
 833        enum dc_lut_mode next_mode;
 834
 835        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 836
 837        if (params == NULL) {
 838                REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0);
 839                return false;
 840        }
 841        current_mode = mpc3_get_shaper_current(mpc, rmu_idx);
 842
 843        if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 844                next_mode = LUT_RAM_B;
 845        else
 846                next_mode = LUT_RAM_A;
 847
 848        mpc3_configure_shaper_lut(mpc, next_mode == LUT_RAM_A ? true:false, rmu_idx);
 849
 850        if (next_mode == LUT_RAM_A)
 851                mpc3_program_shaper_luta_settings(mpc, params, rmu_idx);
 852        else
 853                mpc3_program_shaper_lutb_settings(mpc, params, rmu_idx);
 854
 855        mpc3_program_shaper_lut(
 856                        mpc, params->rgb_resulted, params->hw_points_num, rmu_idx);
 857
 858        REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
 859        mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false);
 860
 861        return true;
 862}
 863
 864static void mpc3_set_3dlut_mode(
 865                struct mpc *mpc,
 866                enum dc_lut_mode mode,
 867                bool is_color_channel_12bits,
 868                bool is_lut_size17x17x17,
 869                uint32_t rmu_idx)
 870{
 871        uint32_t lut_mode;
 872        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 873
 874        if (mode == LUT_BYPASS)
 875                lut_mode = 0;
 876        else if (mode == LUT_RAM_A)
 877                lut_mode = 1;
 878        else
 879                lut_mode = 2;
 880
 881        REG_UPDATE_2(RMU_3DLUT_MODE[rmu_idx],
 882                        MPC_RMU_3DLUT_MODE, lut_mode,
 883                        MPC_RMU_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
 884}
 885
 886static enum dc_lut_mode get3dlut_config(
 887                        struct mpc *mpc,
 888                        bool *is_17x17x17,
 889                        bool *is_12bits_color_channel,
 890                        int rmu_idx)
 891{
 892        uint32_t i_mode, i_enable_10bits, lut_size;
 893        enum dc_lut_mode mode;
 894        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 895
 896        REG_GET(RMU_3DLUT_MODE[rmu_idx],
 897                        MPC_RMU_3DLUT_MODE_CURRENT,  &i_mode);
 898
 899        REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx],
 900                        MPC_RMU_3DLUT_30BIT_EN, &i_enable_10bits);
 901
 902        switch (i_mode) {
 903        case 0:
 904                mode = LUT_BYPASS;
 905                break;
 906        case 1:
 907                mode = LUT_RAM_A;
 908                break;
 909        case 2:
 910                mode = LUT_RAM_B;
 911                break;
 912        default:
 913                mode = LUT_BYPASS;
 914                break;
 915        }
 916        if (i_enable_10bits > 0)
 917                *is_12bits_color_channel = false;
 918        else
 919                *is_12bits_color_channel = true;
 920
 921        REG_GET(RMU_3DLUT_MODE[rmu_idx], MPC_RMU_3DLUT_SIZE, &lut_size);
 922
 923        if (lut_size == 0)
 924                *is_17x17x17 = true;
 925        else
 926                *is_17x17x17 = false;
 927
 928        return mode;
 929}
 930
 931static void mpc3_select_3dlut_ram(
 932                struct mpc *mpc,
 933                enum dc_lut_mode mode,
 934                bool is_color_channel_12bits,
 935                uint32_t rmu_idx)
 936{
 937        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 938
 939        REG_UPDATE_2(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx],
 940                MPC_RMU_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
 941                MPC_RMU_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0:1);
 942}
 943
 944static void mpc3_select_3dlut_ram_mask(
 945                struct mpc *mpc,
 946                uint32_t ram_selection_mask,
 947                uint32_t rmu_idx)
 948{
 949        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 950
 951        REG_UPDATE(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], MPC_RMU_3DLUT_WRITE_EN_MASK,
 952                        ram_selection_mask);
 953        REG_SET(RMU_3DLUT_INDEX[rmu_idx], 0, MPC_RMU_3DLUT_INDEX, 0);
 954}
 955
 956static void mpc3_set3dlut_ram12(
 957                struct mpc *mpc,
 958                const struct dc_rgb *lut,
 959                uint32_t entries,
 960                uint32_t rmu_idx)
 961{
 962        uint32_t i, red, green, blue, red1, green1, blue1;
 963        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 964
 965        for (i = 0 ; i < entries; i += 2) {
 966                red   = lut[i].red<<4;
 967                green = lut[i].green<<4;
 968                blue  = lut[i].blue<<4;
 969                red1   = lut[i+1].red<<4;
 970                green1 = lut[i+1].green<<4;
 971                blue1  = lut[i+1].blue<<4;
 972
 973                REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0,
 974                                MPC_RMU_3DLUT_DATA0, red,
 975                                MPC_RMU_3DLUT_DATA1, red1);
 976
 977                REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0,
 978                                MPC_RMU_3DLUT_DATA0, green,
 979                                MPC_RMU_3DLUT_DATA1, green1);
 980
 981                REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0,
 982                                MPC_RMU_3DLUT_DATA0, blue,
 983                                MPC_RMU_3DLUT_DATA1, blue1);
 984        }
 985}
 986
 987static void mpc3_set3dlut_ram10(
 988                struct mpc *mpc,
 989                const struct dc_rgb *lut,
 990                uint32_t entries,
 991                uint32_t rmu_idx)
 992{
 993        uint32_t i, red, green, blue, value;
 994        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 995
 996        for (i = 0; i < entries; i++) {
 997                red   = lut[i].red;
 998                green = lut[i].green;
 999                blue  = lut[i].blue;
1000                //should we shift red 22bit and green 12? ask Nvenko
1001                value = (red<<20) | (green<<10) | blue;
1002
1003                REG_SET(RMU_3DLUT_DATA_30BIT[rmu_idx], 0, MPC_RMU_3DLUT_DATA_30BIT, value);
1004        }
1005
1006}
1007
1008
1009static void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst)
1010{
1011        mpcc->mpcc_id = mpcc_inst;
1012        mpcc->dpp_id = 0xf;
1013        mpcc->mpcc_bot = NULL;
1014        mpcc->blnd_cfg.overlap_only = false;
1015        mpcc->blnd_cfg.global_alpha = 0xff;
1016        mpcc->blnd_cfg.global_gain = 0xff;
1017        mpcc->blnd_cfg.background_color_bpc = 4;
1018        mpcc->blnd_cfg.bottom_gain_mode = 0;
1019        mpcc->blnd_cfg.top_gain = 0x1f000;
1020        mpcc->blnd_cfg.bottom_inside_gain = 0x1f000;
1021        mpcc->blnd_cfg.bottom_outside_gain = 0x1f000;
1022        mpcc->sm_cfg.enable = false;
1023        mpcc->shared_bottom = false;
1024}
1025
1026static void program_gamut_remap(
1027                struct dcn30_mpc *mpc30,
1028                int mpcc_id,
1029                const uint16_t *regval,
1030                int select)
1031{
1032        uint16_t selection = 0;
1033        struct color_matrices_reg gam_regs;
1034
1035        if (regval == NULL || select == GAMUT_REMAP_BYPASS) {
1036                REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0,
1037                                MPCC_GAMUT_REMAP_MODE, GAMUT_REMAP_BYPASS);
1038                return;
1039        }
1040        switch (select) {
1041        case GAMUT_REMAP_COEFF:
1042                selection = 1;
1043                break;
1044                /*this corresponds to GAMUT_REMAP coefficients set B
1045                 * we don't have common coefficient sets in dcn3ag/dcn3
1046                 */
1047        case GAMUT_REMAP_COMA_COEFF:
1048                selection = 2;
1049                break;
1050        default:
1051                break;
1052        }
1053
1054        gam_regs.shifts.csc_c11 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
1055        gam_regs.masks.csc_c11  = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
1056        gam_regs.shifts.csc_c12 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
1057        gam_regs.masks.csc_c12 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
1058
1059
1060        if (select == GAMUT_REMAP_COEFF) {
1061                gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]);
1062                gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]);
1063
1064                cm_helper_program_color_matrices(
1065                                mpc30->base.ctx,
1066                                regval,
1067                                &gam_regs);
1068
1069        } else  if (select == GAMUT_REMAP_COMA_COEFF) {
1070
1071                gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]);
1072                gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]);
1073
1074                cm_helper_program_color_matrices(
1075                                mpc30->base.ctx,
1076                                regval,
1077                                &gam_regs);
1078
1079        }
1080        //select coefficient set to use
1081        REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0,
1082                                        MPCC_GAMUT_REMAP_MODE, selection);
1083}
1084
1085void mpc3_set_gamut_remap(
1086                struct mpc *mpc,
1087                int mpcc_id,
1088                const struct mpc_grph_gamut_adjustment *adjust)
1089{
1090        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1091        int i = 0;
1092        int gamut_mode;
1093
1094        if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
1095                program_gamut_remap(mpc30, mpcc_id, NULL, GAMUT_REMAP_BYPASS);
1096        else {
1097                struct fixed31_32 arr_matrix[12];
1098                uint16_t arr_reg_val[12];
1099
1100                for (i = 0; i < 12; i++)
1101                        arr_matrix[i] = adjust->temperature_matrix[i];
1102
1103                convert_float_matrix(
1104                        arr_reg_val, arr_matrix, 12);
1105
1106                //current coefficient set in use
1107                REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, &gamut_mode);
1108
1109                if (gamut_mode == 0)
1110                        gamut_mode = 1; //use coefficient set A
1111                else if (gamut_mode == 1)
1112                        gamut_mode = 2;
1113                else
1114                        gamut_mode = 1;
1115
1116                program_gamut_remap(mpc30, mpcc_id, arr_reg_val, gamut_mode);
1117        }
1118}
1119
1120bool mpc3_program_3dlut(
1121                struct mpc *mpc,
1122                const struct tetrahedral_params *params,
1123                int rmu_idx)
1124{
1125        enum dc_lut_mode mode;
1126        bool is_17x17x17;
1127        bool is_12bits_color_channel;
1128        const struct dc_rgb *lut0;
1129        const struct dc_rgb *lut1;
1130        const struct dc_rgb *lut2;
1131        const struct dc_rgb *lut3;
1132        int lut_size0;
1133        int lut_size;
1134
1135        if (params == NULL) {
1136                mpc3_set_3dlut_mode(mpc, LUT_BYPASS, false, false, rmu_idx);
1137                return false;
1138        }
1139        mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true);
1140
1141        mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, rmu_idx);
1142
1143        if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1144                mode = LUT_RAM_A;
1145        else
1146                mode = LUT_RAM_B;
1147
1148        is_17x17x17 = !params->use_tetrahedral_9;
1149        is_12bits_color_channel = params->use_12bits;
1150        if (is_17x17x17) {
1151                lut0 = params->tetrahedral_17.lut0;
1152                lut1 = params->tetrahedral_17.lut1;
1153                lut2 = params->tetrahedral_17.lut2;
1154                lut3 = params->tetrahedral_17.lut3;
1155                lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1156                                        sizeof(params->tetrahedral_17.lut0[0]);
1157                lut_size  = sizeof(params->tetrahedral_17.lut1)/
1158                                        sizeof(params->tetrahedral_17.lut1[0]);
1159        } else {
1160                lut0 = params->tetrahedral_9.lut0;
1161                lut1 = params->tetrahedral_9.lut1;
1162                lut2 = params->tetrahedral_9.lut2;
1163                lut3 = params->tetrahedral_9.lut3;
1164                lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1165                                sizeof(params->tetrahedral_9.lut0[0]);
1166                lut_size  = sizeof(params->tetrahedral_9.lut1)/
1167                                sizeof(params->tetrahedral_9.lut1[0]);
1168                }
1169
1170        mpc3_select_3dlut_ram(mpc, mode,
1171                                is_12bits_color_channel, rmu_idx);
1172        mpc3_select_3dlut_ram_mask(mpc, 0x1, rmu_idx);
1173        if (is_12bits_color_channel)
1174                mpc3_set3dlut_ram12(mpc, lut0, lut_size0, rmu_idx);
1175        else
1176                mpc3_set3dlut_ram10(mpc, lut0, lut_size0, rmu_idx);
1177
1178        mpc3_select_3dlut_ram_mask(mpc, 0x2, rmu_idx);
1179        if (is_12bits_color_channel)
1180                mpc3_set3dlut_ram12(mpc, lut1, lut_size, rmu_idx);
1181        else
1182                mpc3_set3dlut_ram10(mpc, lut1, lut_size, rmu_idx);
1183
1184        mpc3_select_3dlut_ram_mask(mpc, 0x4, rmu_idx);
1185        if (is_12bits_color_channel)
1186                mpc3_set3dlut_ram12(mpc, lut2, lut_size, rmu_idx);
1187        else
1188                mpc3_set3dlut_ram10(mpc, lut2, lut_size, rmu_idx);
1189
1190        mpc3_select_3dlut_ram_mask(mpc, 0x8, rmu_idx);
1191        if (is_12bits_color_channel)
1192                mpc3_set3dlut_ram12(mpc, lut3, lut_size, rmu_idx);
1193        else
1194                mpc3_set3dlut_ram10(mpc, lut3, lut_size, rmu_idx);
1195
1196        mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel,
1197                                        is_17x17x17, rmu_idx);
1198
1199        return true;
1200}
1201
1202void mpc3_set_output_csc(
1203                struct mpc *mpc,
1204                int opp_id,
1205                const uint16_t *regval,
1206                enum mpc_output_csc_mode ocsc_mode)
1207{
1208        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1209        struct color_matrices_reg ocsc_regs;
1210
1211        REG_WRITE(MPC_OUT_CSC_COEF_FORMAT, 0);
1212
1213        REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
1214
1215        if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
1216                return;
1217
1218        if (regval == NULL) {
1219                BREAK_TO_DEBUGGER();
1220                return;
1221        }
1222
1223        ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A;
1224        ocsc_regs.masks.csc_c11  = mpc30->mpc_mask->MPC_OCSC_C11_A;
1225        ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A;
1226        ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A;
1227
1228        if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) {
1229                ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]);
1230                ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]);
1231        } else {
1232                ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]);
1233                ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]);
1234        }
1235        cm_helper_program_color_matrices(
1236                        mpc30->base.ctx,
1237                        regval,
1238                        &ocsc_regs);
1239}
1240
1241void mpc3_set_ocsc_default(
1242                struct mpc *mpc,
1243                int opp_id,
1244                enum dc_color_space color_space,
1245                enum mpc_output_csc_mode ocsc_mode)
1246{
1247        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1248        uint32_t arr_size;
1249        struct color_matrices_reg ocsc_regs;
1250        const uint16_t *regval = NULL;
1251
1252        REG_WRITE(MPC_OUT_CSC_COEF_FORMAT, 0);
1253
1254        REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
1255        if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
1256                return;
1257
1258        regval = find_color_matrix(color_space, &arr_size);
1259
1260        if (regval == NULL) {
1261                BREAK_TO_DEBUGGER();
1262                return;
1263        }
1264
1265        ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A;
1266        ocsc_regs.masks.csc_c11  = mpc30->mpc_mask->MPC_OCSC_C11_A;
1267        ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A;
1268        ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A;
1269
1270
1271        if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) {
1272                ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]);
1273                ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]);
1274        } else {
1275                ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]);
1276                ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]);
1277        }
1278
1279        cm_helper_program_color_matrices(
1280                        mpc30->base.ctx,
1281                        regval,
1282                        &ocsc_regs);
1283}
1284
1285void mpc3_set_rmu_mux(
1286        struct mpc *mpc,
1287        int rmu_idx,
1288        int value)
1289{
1290        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1291
1292        if (rmu_idx == 0)
1293                REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU0_MUX, value);
1294        else if (rmu_idx == 1)
1295                REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU1_MUX, value);
1296
1297}
1298
1299uint32_t mpc3_get_rmu_mux_status(
1300        struct mpc *mpc,
1301        int rmu_idx)
1302{
1303        uint32_t status = 0xf;
1304        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1305
1306        if (rmu_idx == 0)
1307                REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, &status);
1308        else if (rmu_idx == 1)
1309                REG_GET(MPC_RMU_CONTROL, MPC_RMU1_MUX_STATUS, &status);
1310
1311        return status;
1312}
1313
1314uint32_t mpcc3_acquire_rmu(struct mpc *mpc, int mpcc_id, int rmu_idx)
1315{
1316        uint32_t rmu_status;
1317
1318        //determine if this mpcc is already multiplexed to an RMU unit
1319        rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx);
1320        if (rmu_status == mpcc_id)
1321                //return rmu_idx of pre_acquired rmu unit
1322                return rmu_idx;
1323
1324        if (rmu_status == 0xf) {//rmu unit is disabled
1325                mpc3_set_rmu_mux(mpc, rmu_idx, mpcc_id);
1326                return rmu_idx;
1327        }
1328
1329        //no vacant RMU units or invalid parameters acquire_post_bldn_3dlut
1330        return -1;
1331}
1332
1333int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id)
1334{
1335        struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1336        int rmu_idx;
1337        uint32_t rmu_status;
1338        int released_rmu = -1;
1339
1340        for (rmu_idx = 0; rmu_idx < mpc30->num_rmu; rmu_idx++) {
1341                rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx);
1342                if (rmu_status == mpcc_id) {
1343                        mpc3_set_rmu_mux(mpc, rmu_idx, 0xf);
1344                        released_rmu = rmu_idx;
1345                        break;
1346                }
1347        }
1348        return released_rmu;
1349
1350}
1351
1352const struct mpc_funcs dcn30_mpc_funcs = {
1353        .read_mpcc_state = mpc1_read_mpcc_state,
1354        .insert_plane = mpc1_insert_plane,
1355        .remove_mpcc = mpc1_remove_mpcc,
1356        .mpc_init = mpc1_mpc_init,
1357        .mpc_init_single_inst = mpc1_mpc_init_single_inst,
1358        .update_blending = mpc2_update_blending,
1359        .cursor_lock = mpc1_cursor_lock,
1360        .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
1361        .wait_for_idle = mpc2_assert_idle_mpcc,
1362        .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
1363        .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
1364        .set_denorm =  mpc3_set_denorm,
1365        .set_denorm_clamp = mpc3_set_denorm_clamp,
1366        .set_output_csc = mpc3_set_output_csc,
1367        .set_ocsc_default = mpc3_set_ocsc_default,
1368        .set_output_gamma = mpc3_set_output_gamma,
1369        .insert_plane_to_secondary = NULL,
1370        .remove_mpcc_from_secondary =  NULL,
1371        .set_dwb_mux = mpc3_set_dwb_mux,
1372        .disable_dwb_mux = mpc3_disable_dwb_mux,
1373        .is_dwb_idle = mpc3_is_dwb_idle,
1374        .set_out_rate_control = mpc3_set_out_rate_control,
1375        .set_gamut_remap = mpc3_set_gamut_remap,
1376        .program_shaper = mpc3_program_shaper,
1377        .acquire_rmu = mpcc3_acquire_rmu,
1378        .program_3dlut = mpc3_program_3dlut,
1379        .release_rmu = mpcc3_release_rmu,
1380        .power_on_mpc_mem_pwr = mpc20_power_on_ogam_lut,
1381
1382};
1383
1384void dcn30_mpc_construct(struct dcn30_mpc *mpc30,
1385        struct dc_context *ctx,
1386        const struct dcn30_mpc_registers *mpc_regs,
1387        const struct dcn30_mpc_shift *mpc_shift,
1388        const struct dcn30_mpc_mask *mpc_mask,
1389        int num_mpcc,
1390        int num_rmu)
1391{
1392        int i;
1393
1394        mpc30->base.ctx = ctx;
1395
1396        mpc30->base.funcs = &dcn30_mpc_funcs;
1397
1398        mpc30->mpc_regs = mpc_regs;
1399        mpc30->mpc_shift = mpc_shift;
1400        mpc30->mpc_mask = mpc_mask;
1401
1402        mpc30->mpcc_in_use_mask = 0;
1403        mpc30->num_mpcc = num_mpcc;
1404        mpc30->num_rmu = num_rmu;
1405
1406        for (i = 0; i < MAX_MPCC; i++)
1407                mpc3_init_mpcc(&mpc30->base.mpcc_array[i], i);
1408}
1409
1410