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