2 * Copyright 2012-15 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include "dm_services.h"
28 /* include DCE11 register header files */
29 #include "dce/dce_11_0_d.h"
30 #include "dce/dce_11_0_sh_mask.h"
32 #include "dce110_transform_v.h"
34 static void power_on_lut(struct transform *xfm,
35 bool power_on, bool inputgamma, bool regamma)
37 uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
46 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
52 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
59 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
65 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
68 dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
70 for (i = 0; i < 3; i++) {
71 value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
72 if (get_reg_field_value(value,
74 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) &&
75 get_reg_field_value(value,
77 COL_MAN_GAMMA_CORR_MEM_PWR_DIS))
84 static void set_bypass_input_gamma(struct dce_transform *xfm_dce)
88 value = dm_read_reg(xfm_dce->base.ctx,
89 mmCOL_MAN_INPUT_GAMMA_CONTROL1);
94 COL_MAN_INPUT_GAMMA_CONTROL1,
97 dm_write_reg(xfm_dce->base.ctx,
98 mmCOL_MAN_INPUT_GAMMA_CONTROL1, value);
101 static void configure_regamma_mode(struct dce_transform *xfm_dce, uint32_t mode)
111 dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CONTROL, 0);
115 *****************************************************************************
116 * Function: regamma_config_regions_and_segments
118 * build regamma curve by using predefined hw points
119 * uses interface parameters ,like EDID coeff.
121 * @param : parameters interface parameters
128 *****************************************************************************
130 static void regamma_config_regions_and_segments(
131 struct dce_transform *xfm_dce, const struct pwl_params *params)
133 const struct gamma_curve *curve;
139 params->arr_points[0].custom_float_x,
140 GAMMA_CORR_CNTLA_START_CNTL,
141 GAMMA_CORR_CNTLA_EXP_REGION_START);
146 GAMMA_CORR_CNTLA_START_CNTL,
147 GAMMA_CORR_CNTLA_EXP_REGION_START_SEGMENT);
149 dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CNTLA_START_CNTL,
156 params->arr_points[0].custom_float_slope,
157 GAMMA_CORR_CNTLA_SLOPE_CNTL,
158 GAMMA_CORR_CNTLA_EXP_REGION_LINEAR_SLOPE);
160 dm_write_reg(xfm_dce->base.ctx,
161 mmGAMMA_CORR_CNTLA_SLOPE_CNTL, value);
167 params->arr_points[1].custom_float_x,
168 GAMMA_CORR_CNTLA_END_CNTL1,
169 GAMMA_CORR_CNTLA_EXP_REGION_END);
171 dm_write_reg(xfm_dce->base.ctx,
172 mmGAMMA_CORR_CNTLA_END_CNTL1, value);
178 params->arr_points[1].custom_float_slope,
179 GAMMA_CORR_CNTLA_END_CNTL2,
180 GAMMA_CORR_CNTLA_EXP_REGION_END_BASE);
184 params->arr_points[1].custom_float_y,
185 GAMMA_CORR_CNTLA_END_CNTL2,
186 GAMMA_CORR_CNTLA_EXP_REGION_END_SLOPE);
188 dm_write_reg(xfm_dce->base.ctx,
189 mmGAMMA_CORR_CNTLA_END_CNTL2, value);
192 curve = params->arr_curve_points;
199 GAMMA_CORR_CNTLA_REGION_0_1,
200 GAMMA_CORR_CNTLA_EXP_REGION0_LUT_OFFSET);
204 curve[0].segments_num,
205 GAMMA_CORR_CNTLA_REGION_0_1,
206 GAMMA_CORR_CNTLA_EXP_REGION0_NUM_SEGMENTS);
211 GAMMA_CORR_CNTLA_REGION_0_1,
212 GAMMA_CORR_CNTLA_EXP_REGION1_LUT_OFFSET);
216 curve[1].segments_num,
217 GAMMA_CORR_CNTLA_REGION_0_1,
218 GAMMA_CORR_CNTLA_EXP_REGION1_NUM_SEGMENTS);
222 mmGAMMA_CORR_CNTLA_REGION_0_1,
232 GAMMA_CORR_CNTLA_REGION_2_3,
233 GAMMA_CORR_CNTLA_EXP_REGION2_LUT_OFFSET);
237 curve[0].segments_num,
238 GAMMA_CORR_CNTLA_REGION_2_3,
239 GAMMA_CORR_CNTLA_EXP_REGION2_NUM_SEGMENTS);
244 GAMMA_CORR_CNTLA_REGION_2_3,
245 GAMMA_CORR_CNTLA_EXP_REGION3_LUT_OFFSET);
249 curve[1].segments_num,
250 GAMMA_CORR_CNTLA_REGION_2_3,
251 GAMMA_CORR_CNTLA_EXP_REGION3_NUM_SEGMENTS);
253 dm_write_reg(xfm_dce->base.ctx,
254 mmGAMMA_CORR_CNTLA_REGION_2_3,
264 GAMMA_CORR_CNTLA_REGION_4_5,
265 GAMMA_CORR_CNTLA_EXP_REGION4_LUT_OFFSET);
269 curve[0].segments_num,
270 GAMMA_CORR_CNTLA_REGION_4_5,
271 GAMMA_CORR_CNTLA_EXP_REGION4_NUM_SEGMENTS);
276 GAMMA_CORR_CNTLA_REGION_4_5,
277 GAMMA_CORR_CNTLA_EXP_REGION5_LUT_OFFSET);
281 curve[1].segments_num,
282 GAMMA_CORR_CNTLA_REGION_4_5,
283 GAMMA_CORR_CNTLA_EXP_REGION5_NUM_SEGMENTS);
285 dm_write_reg(xfm_dce->base.ctx,
286 mmGAMMA_CORR_CNTLA_REGION_4_5,
296 GAMMA_CORR_CNTLA_REGION_6_7,
297 GAMMA_CORR_CNTLA_EXP_REGION6_LUT_OFFSET);
301 curve[0].segments_num,
302 GAMMA_CORR_CNTLA_REGION_6_7,
303 GAMMA_CORR_CNTLA_EXP_REGION6_NUM_SEGMENTS);
308 GAMMA_CORR_CNTLA_REGION_6_7,
309 GAMMA_CORR_CNTLA_EXP_REGION7_LUT_OFFSET);
313 curve[1].segments_num,
314 GAMMA_CORR_CNTLA_REGION_6_7,
315 GAMMA_CORR_CNTLA_EXP_REGION7_NUM_SEGMENTS);
317 dm_write_reg(xfm_dce->base.ctx,
318 mmGAMMA_CORR_CNTLA_REGION_6_7,
328 GAMMA_CORR_CNTLA_REGION_8_9,
329 GAMMA_CORR_CNTLA_EXP_REGION8_LUT_OFFSET);
333 curve[0].segments_num,
334 GAMMA_CORR_CNTLA_REGION_8_9,
335 GAMMA_CORR_CNTLA_EXP_REGION8_NUM_SEGMENTS);
340 GAMMA_CORR_CNTLA_REGION_8_9,
341 GAMMA_CORR_CNTLA_EXP_REGION9_LUT_OFFSET);
345 curve[1].segments_num,
346 GAMMA_CORR_CNTLA_REGION_8_9,
347 GAMMA_CORR_CNTLA_EXP_REGION9_NUM_SEGMENTS);
349 dm_write_reg(xfm_dce->base.ctx,
350 mmGAMMA_CORR_CNTLA_REGION_8_9,
360 GAMMA_CORR_CNTLA_REGION_10_11,
361 GAMMA_CORR_CNTLA_EXP_REGION10_LUT_OFFSET);
365 curve[0].segments_num,
366 GAMMA_CORR_CNTLA_REGION_10_11,
367 GAMMA_CORR_CNTLA_EXP_REGION10_NUM_SEGMENTS);
372 GAMMA_CORR_CNTLA_REGION_10_11,
373 GAMMA_CORR_CNTLA_EXP_REGION11_LUT_OFFSET);
377 curve[1].segments_num,
378 GAMMA_CORR_CNTLA_REGION_10_11,
379 GAMMA_CORR_CNTLA_EXP_REGION11_NUM_SEGMENTS);
381 dm_write_reg(xfm_dce->base.ctx,
382 mmGAMMA_CORR_CNTLA_REGION_10_11,
392 GAMMA_CORR_CNTLA_REGION_12_13,
393 GAMMA_CORR_CNTLA_EXP_REGION12_LUT_OFFSET);
397 curve[0].segments_num,
398 GAMMA_CORR_CNTLA_REGION_12_13,
399 GAMMA_CORR_CNTLA_EXP_REGION12_NUM_SEGMENTS);
404 GAMMA_CORR_CNTLA_REGION_12_13,
405 GAMMA_CORR_CNTLA_EXP_REGION13_LUT_OFFSET);
409 curve[1].segments_num,
410 GAMMA_CORR_CNTLA_REGION_12_13,
411 GAMMA_CORR_CNTLA_EXP_REGION13_NUM_SEGMENTS);
413 dm_write_reg(xfm_dce->base.ctx,
414 mmGAMMA_CORR_CNTLA_REGION_12_13,
424 GAMMA_CORR_CNTLA_REGION_14_15,
425 GAMMA_CORR_CNTLA_EXP_REGION14_LUT_OFFSET);
429 curve[0].segments_num,
430 GAMMA_CORR_CNTLA_REGION_14_15,
431 GAMMA_CORR_CNTLA_EXP_REGION14_NUM_SEGMENTS);
436 GAMMA_CORR_CNTLA_REGION_14_15,
437 GAMMA_CORR_CNTLA_EXP_REGION15_LUT_OFFSET);
441 curve[1].segments_num,
442 GAMMA_CORR_CNTLA_REGION_14_15,
443 GAMMA_CORR_CNTLA_EXP_REGION15_NUM_SEGMENTS);
445 dm_write_reg(xfm_dce->base.ctx,
446 mmGAMMA_CORR_CNTLA_REGION_14_15,
451 static void program_pwl(struct dce_transform *xfm_dce,
452 const struct pwl_params *params)
459 GAMMA_CORR_LUT_WRITE_EN_MASK,
460 GAMMA_CORR_LUT_WRITE_EN_MASK);
462 dm_write_reg(xfm_dce->base.ctx,
463 mmGAMMA_CORR_LUT_WRITE_EN_MASK, value);
465 dm_write_reg(xfm_dce->base.ctx,
466 mmGAMMA_CORR_LUT_INDEX, 0);
468 /* Program REGAMMA_LUT_DATA */
470 const uint32_t addr = mmGAMMA_CORR_LUT_DATA;
472 const struct pwl_result_data *rgb =
473 params->rgb_resulted;
475 while (i != params->hw_points_num) {
476 dm_write_reg(xfm_dce->base.ctx, addr, rgb->red_reg);
477 dm_write_reg(xfm_dce->base.ctx, addr, rgb->green_reg);
478 dm_write_reg(xfm_dce->base.ctx, addr, rgb->blue_reg);
480 dm_write_reg(xfm_dce->base.ctx, addr,
482 dm_write_reg(xfm_dce->base.ctx, addr,
483 rgb->delta_green_reg);
484 dm_write_reg(xfm_dce->base.ctx, addr,
485 rgb->delta_blue_reg);
493 void dce110_opp_program_regamma_pwl_v(
494 struct transform *xfm,
495 const struct pwl_params *params)
497 struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
500 regamma_config_regions_and_segments(xfm_dce, params);
502 set_bypass_input_gamma(xfm_dce);
504 /* Power on gamma LUT memory */
505 power_on_lut(xfm, true, false, true);
508 program_pwl(xfm_dce, params);
510 /* program regamma config */
511 configure_regamma_mode(xfm_dce, 1);
513 /* Power return to auto back */
514 power_on_lut(xfm, false, false, true);
517 void dce110_opp_power_on_regamma_lut_v(
518 struct transform *xfm,
521 uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
527 COL_MAN_GAMMA_CORR_MEM_PWR_FORCE);
533 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
539 COL_MAN_INPUT_GAMMA_MEM_PWR_FORCE);
545 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
547 dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
550 void dce110_opp_set_regamma_mode_v(
551 struct transform *xfm,
552 enum opp_regamma mode)
554 // TODO: need to implement the function