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