Merge tag 'timers-urgent-2020-09-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn30 / dcn30_mpc.c
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
47 static 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
62 static 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
73 static 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
83 static 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
102 static 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
140 static 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
150 static 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
163 static 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
197 static 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
230 static 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
264 static 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
320 void 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
365 void 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
404 void 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
423 static 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
449 static 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
463 static 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
612 static 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
763 static 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
796 static 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
827 bool 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
864 static 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
886 static 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
931 static 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
944 static 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
956 static 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
987 static 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
1009 static 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
1026 static 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
1085 void 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
1120 bool 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
1202 void 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
1241 void 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
1285 void 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
1299 uint32_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
1314 uint32_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
1333 int 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
1352 const 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
1384 void 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