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 <linux/delay.h>
28 #include "dm_services.h"
30 /* include DCE11 register header files */
31 #include "dce/dce_11_0_d.h"
32 #include "dce/dce_11_0_sh_mask.h"
34 #include "dce110_transform_v.h"
36 static void power_on_lut(struct transform *xfm,
37 bool power_on, bool inputgamma, bool regamma)
39 uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
48 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
54 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
61 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
67 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
70 dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
72 for (i = 0; i < 3; i++) {
73 value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
74 if (get_reg_field_value(value,
76 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) &&
77 get_reg_field_value(value,
79 COL_MAN_GAMMA_CORR_MEM_PWR_DIS))
86 static void set_bypass_input_gamma(struct dce_transform *xfm_dce)
90 value = dm_read_reg(xfm_dce->base.ctx,
91 mmCOL_MAN_INPUT_GAMMA_CONTROL1);
96 COL_MAN_INPUT_GAMMA_CONTROL1,
99 dm_write_reg(xfm_dce->base.ctx,
100 mmCOL_MAN_INPUT_GAMMA_CONTROL1, value);
103 static void configure_regamma_mode(struct dce_transform *xfm_dce, uint32_t mode)
113 dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CONTROL, 0);
117 *****************************************************************************
118 * Function: regamma_config_regions_and_segments
120 * build regamma curve by using predefined hw points
121 * uses interface parameters ,like EDID coeff.
123 * @param : parameters interface parameters
130 *****************************************************************************
132 static void regamma_config_regions_and_segments(
133 struct dce_transform *xfm_dce, const struct pwl_params *params)
135 const struct gamma_curve *curve;
141 params->arr_points[0].custom_float_x,
142 GAMMA_CORR_CNTLA_START_CNTL,
143 GAMMA_CORR_CNTLA_EXP_REGION_START);
148 GAMMA_CORR_CNTLA_START_CNTL,
149 GAMMA_CORR_CNTLA_EXP_REGION_START_SEGMENT);
151 dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CNTLA_START_CNTL,
158 params->arr_points[0].custom_float_slope,
159 GAMMA_CORR_CNTLA_SLOPE_CNTL,
160 GAMMA_CORR_CNTLA_EXP_REGION_LINEAR_SLOPE);
162 dm_write_reg(xfm_dce->base.ctx,
163 mmGAMMA_CORR_CNTLA_SLOPE_CNTL, value);
169 params->arr_points[1].custom_float_x,
170 GAMMA_CORR_CNTLA_END_CNTL1,
171 GAMMA_CORR_CNTLA_EXP_REGION_END);
173 dm_write_reg(xfm_dce->base.ctx,
174 mmGAMMA_CORR_CNTLA_END_CNTL1, value);
180 params->arr_points[1].custom_float_slope,
181 GAMMA_CORR_CNTLA_END_CNTL2,
182 GAMMA_CORR_CNTLA_EXP_REGION_END_BASE);
186 params->arr_points[1].custom_float_y,
187 GAMMA_CORR_CNTLA_END_CNTL2,
188 GAMMA_CORR_CNTLA_EXP_REGION_END_SLOPE);
190 dm_write_reg(xfm_dce->base.ctx,
191 mmGAMMA_CORR_CNTLA_END_CNTL2, value);
194 curve = params->arr_curve_points;
201 GAMMA_CORR_CNTLA_REGION_0_1,
202 GAMMA_CORR_CNTLA_EXP_REGION0_LUT_OFFSET);
206 curve[0].segments_num,
207 GAMMA_CORR_CNTLA_REGION_0_1,
208 GAMMA_CORR_CNTLA_EXP_REGION0_NUM_SEGMENTS);
213 GAMMA_CORR_CNTLA_REGION_0_1,
214 GAMMA_CORR_CNTLA_EXP_REGION1_LUT_OFFSET);
218 curve[1].segments_num,
219 GAMMA_CORR_CNTLA_REGION_0_1,
220 GAMMA_CORR_CNTLA_EXP_REGION1_NUM_SEGMENTS);
224 mmGAMMA_CORR_CNTLA_REGION_0_1,
234 GAMMA_CORR_CNTLA_REGION_2_3,
235 GAMMA_CORR_CNTLA_EXP_REGION2_LUT_OFFSET);
239 curve[0].segments_num,
240 GAMMA_CORR_CNTLA_REGION_2_3,
241 GAMMA_CORR_CNTLA_EXP_REGION2_NUM_SEGMENTS);
246 GAMMA_CORR_CNTLA_REGION_2_3,
247 GAMMA_CORR_CNTLA_EXP_REGION3_LUT_OFFSET);
251 curve[1].segments_num,
252 GAMMA_CORR_CNTLA_REGION_2_3,
253 GAMMA_CORR_CNTLA_EXP_REGION3_NUM_SEGMENTS);
255 dm_write_reg(xfm_dce->base.ctx,
256 mmGAMMA_CORR_CNTLA_REGION_2_3,
266 GAMMA_CORR_CNTLA_REGION_4_5,
267 GAMMA_CORR_CNTLA_EXP_REGION4_LUT_OFFSET);
271 curve[0].segments_num,
272 GAMMA_CORR_CNTLA_REGION_4_5,
273 GAMMA_CORR_CNTLA_EXP_REGION4_NUM_SEGMENTS);
278 GAMMA_CORR_CNTLA_REGION_4_5,
279 GAMMA_CORR_CNTLA_EXP_REGION5_LUT_OFFSET);
283 curve[1].segments_num,
284 GAMMA_CORR_CNTLA_REGION_4_5,
285 GAMMA_CORR_CNTLA_EXP_REGION5_NUM_SEGMENTS);
287 dm_write_reg(xfm_dce->base.ctx,
288 mmGAMMA_CORR_CNTLA_REGION_4_5,
298 GAMMA_CORR_CNTLA_REGION_6_7,
299 GAMMA_CORR_CNTLA_EXP_REGION6_LUT_OFFSET);
303 curve[0].segments_num,
304 GAMMA_CORR_CNTLA_REGION_6_7,
305 GAMMA_CORR_CNTLA_EXP_REGION6_NUM_SEGMENTS);
310 GAMMA_CORR_CNTLA_REGION_6_7,
311 GAMMA_CORR_CNTLA_EXP_REGION7_LUT_OFFSET);
315 curve[1].segments_num,
316 GAMMA_CORR_CNTLA_REGION_6_7,
317 GAMMA_CORR_CNTLA_EXP_REGION7_NUM_SEGMENTS);
319 dm_write_reg(xfm_dce->base.ctx,
320 mmGAMMA_CORR_CNTLA_REGION_6_7,
330 GAMMA_CORR_CNTLA_REGION_8_9,
331 GAMMA_CORR_CNTLA_EXP_REGION8_LUT_OFFSET);
335 curve[0].segments_num,
336 GAMMA_CORR_CNTLA_REGION_8_9,
337 GAMMA_CORR_CNTLA_EXP_REGION8_NUM_SEGMENTS);
342 GAMMA_CORR_CNTLA_REGION_8_9,
343 GAMMA_CORR_CNTLA_EXP_REGION9_LUT_OFFSET);
347 curve[1].segments_num,
348 GAMMA_CORR_CNTLA_REGION_8_9,
349 GAMMA_CORR_CNTLA_EXP_REGION9_NUM_SEGMENTS);
351 dm_write_reg(xfm_dce->base.ctx,
352 mmGAMMA_CORR_CNTLA_REGION_8_9,
362 GAMMA_CORR_CNTLA_REGION_10_11,
363 GAMMA_CORR_CNTLA_EXP_REGION10_LUT_OFFSET);
367 curve[0].segments_num,
368 GAMMA_CORR_CNTLA_REGION_10_11,
369 GAMMA_CORR_CNTLA_EXP_REGION10_NUM_SEGMENTS);
374 GAMMA_CORR_CNTLA_REGION_10_11,
375 GAMMA_CORR_CNTLA_EXP_REGION11_LUT_OFFSET);
379 curve[1].segments_num,
380 GAMMA_CORR_CNTLA_REGION_10_11,
381 GAMMA_CORR_CNTLA_EXP_REGION11_NUM_SEGMENTS);
383 dm_write_reg(xfm_dce->base.ctx,
384 mmGAMMA_CORR_CNTLA_REGION_10_11,
394 GAMMA_CORR_CNTLA_REGION_12_13,
395 GAMMA_CORR_CNTLA_EXP_REGION12_LUT_OFFSET);
399 curve[0].segments_num,
400 GAMMA_CORR_CNTLA_REGION_12_13,
401 GAMMA_CORR_CNTLA_EXP_REGION12_NUM_SEGMENTS);
406 GAMMA_CORR_CNTLA_REGION_12_13,
407 GAMMA_CORR_CNTLA_EXP_REGION13_LUT_OFFSET);
411 curve[1].segments_num,
412 GAMMA_CORR_CNTLA_REGION_12_13,
413 GAMMA_CORR_CNTLA_EXP_REGION13_NUM_SEGMENTS);
415 dm_write_reg(xfm_dce->base.ctx,
416 mmGAMMA_CORR_CNTLA_REGION_12_13,
426 GAMMA_CORR_CNTLA_REGION_14_15,
427 GAMMA_CORR_CNTLA_EXP_REGION14_LUT_OFFSET);
431 curve[0].segments_num,
432 GAMMA_CORR_CNTLA_REGION_14_15,
433 GAMMA_CORR_CNTLA_EXP_REGION14_NUM_SEGMENTS);
438 GAMMA_CORR_CNTLA_REGION_14_15,
439 GAMMA_CORR_CNTLA_EXP_REGION15_LUT_OFFSET);
443 curve[1].segments_num,
444 GAMMA_CORR_CNTLA_REGION_14_15,
445 GAMMA_CORR_CNTLA_EXP_REGION15_NUM_SEGMENTS);
447 dm_write_reg(xfm_dce->base.ctx,
448 mmGAMMA_CORR_CNTLA_REGION_14_15,
453 static void program_pwl(struct dce_transform *xfm_dce,
454 const struct pwl_params *params)
461 GAMMA_CORR_LUT_WRITE_EN_MASK,
462 GAMMA_CORR_LUT_WRITE_EN_MASK);
464 dm_write_reg(xfm_dce->base.ctx,
465 mmGAMMA_CORR_LUT_WRITE_EN_MASK, value);
467 dm_write_reg(xfm_dce->base.ctx,
468 mmGAMMA_CORR_LUT_INDEX, 0);
470 /* Program REGAMMA_LUT_DATA */
472 const uint32_t addr = mmGAMMA_CORR_LUT_DATA;
474 const struct pwl_result_data *rgb =
475 params->rgb_resulted;
477 while (i != params->hw_points_num) {
478 dm_write_reg(xfm_dce->base.ctx, addr, rgb->red_reg);
479 dm_write_reg(xfm_dce->base.ctx, addr, rgb->green_reg);
480 dm_write_reg(xfm_dce->base.ctx, addr, rgb->blue_reg);
482 dm_write_reg(xfm_dce->base.ctx, addr,
484 dm_write_reg(xfm_dce->base.ctx, addr,
485 rgb->delta_green_reg);
486 dm_write_reg(xfm_dce->base.ctx, addr,
487 rgb->delta_blue_reg);
495 void dce110_opp_program_regamma_pwl_v(
496 struct transform *xfm,
497 const struct pwl_params *params)
499 struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
502 regamma_config_regions_and_segments(xfm_dce, params);
504 set_bypass_input_gamma(xfm_dce);
506 /* Power on gamma LUT memory */
507 power_on_lut(xfm, true, false, true);
510 program_pwl(xfm_dce, params);
512 /* program regamma config */
513 configure_regamma_mode(xfm_dce, 1);
515 /* Power return to auto back */
516 power_on_lut(xfm, false, false, true);
519 void dce110_opp_power_on_regamma_lut_v(
520 struct transform *xfm,
523 uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
529 COL_MAN_GAMMA_CORR_MEM_PWR_FORCE);
535 COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
541 COL_MAN_INPUT_GAMMA_MEM_PWR_FORCE);
547 COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
549 dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
552 void dce110_opp_set_regamma_mode_v(
553 struct transform *xfm,
554 enum opp_regamma mode)
556 // TODO: need to implement the function