]>
Commit | Line | Data |
---|---|---|
b708205f BL |
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 | ||
737b2b53 NK |
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); | |
b708205f BL |
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 ? true:false); | |
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); | |
3e5b4cdf | 373 | |
cae78e03 | 374 | if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) |
3e5b4cdf | 375 | mpc3_power_on_ogam_lut(mpc, mpcc_id, false); |
b708205f BL |
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); | |
3e5b4cdf | 817 | int max_retries = 10; |
b708205f BL |
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); | |
3e5b4cdf | 822 | /* wait for memory to fully power up */ |
cae78e03 | 823 | if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { |
3e5b4cdf JL |
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 | ||
b708205f BL |
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); | |
cae78e03 | 834 | if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { |
3e5b4cdf JL |
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 | ||
b708205f BL |
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 | } | |
3e5b4cdf | 866 | |
cae78e03 | 867 | if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) |
3e5b4cdf JL |
868 | mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true); |
869 | ||
b708205f BL |
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 ? true:false, 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 | ||
cae78e03 | 1228 | if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) |
3e5b4cdf JL |
1229 | mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false); |
1230 | ||
b708205f BL |
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 | ||
3e5b4cdf JL |
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 | ||
cae78e03 | 1391 | if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { |
3e5b4cdf JL |
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 | ||
b708205f BL |
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, | |
3e5b4cdf | 1408 | .mpc_init = mpc3_mpc_init, |
b708205f BL |
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, | |
737b2b53 | 1432 | .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut, |
110b055b | 1433 | .get_mpc_out_mux = mpc1_get_mpc_out_mux, |
b708205f BL |
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 |