Line data Source code
1 : /*
2 : * Copyright 2012-15 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 "dm_services.h"
27 :
28 : /* include DCE11 register header files */
29 : #include "dce/dce_11_0_d.h"
30 : #include "dce/dce_11_0_sh_mask.h"
31 :
32 : #include "dce110_transform_v.h"
33 :
34 0 : static void power_on_lut(struct transform *xfm,
35 : bool power_on, bool inputgamma, bool regamma)
36 : {
37 0 : uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
38 : int i;
39 :
40 0 : if (power_on) {
41 0 : if (inputgamma)
42 0 : set_reg_field_value(
43 : value,
44 : 1,
45 : DCFEV_MEM_PWR_CTRL,
46 : COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
47 0 : if (regamma)
48 0 : set_reg_field_value(
49 : value,
50 : 1,
51 : DCFEV_MEM_PWR_CTRL,
52 : COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
53 : } else {
54 0 : if (inputgamma)
55 0 : set_reg_field_value(
56 : value,
57 : 0,
58 : DCFEV_MEM_PWR_CTRL,
59 : COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
60 0 : if (regamma)
61 0 : set_reg_field_value(
62 : value,
63 : 0,
64 : DCFEV_MEM_PWR_CTRL,
65 : COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
66 : }
67 :
68 0 : dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
69 :
70 0 : for (i = 0; i < 3; i++) {
71 0 : value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
72 0 : if (get_reg_field_value(value,
73 : DCFEV_MEM_PWR_CTRL,
74 0 : COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) &&
75 0 : get_reg_field_value(value,
76 : DCFEV_MEM_PWR_CTRL,
77 : COL_MAN_GAMMA_CORR_MEM_PWR_DIS))
78 : break;
79 :
80 0 : udelay(2);
81 : }
82 0 : }
83 :
84 0 : static void set_bypass_input_gamma(struct dce_transform *xfm_dce)
85 : {
86 : uint32_t value;
87 :
88 0 : value = dm_read_reg(xfm_dce->base.ctx,
89 : mmCOL_MAN_INPUT_GAMMA_CONTROL1);
90 :
91 0 : set_reg_field_value(
92 : value,
93 : 0,
94 : COL_MAN_INPUT_GAMMA_CONTROL1,
95 : INPUT_GAMMA_MODE);
96 :
97 0 : dm_write_reg(xfm_dce->base.ctx,
98 : mmCOL_MAN_INPUT_GAMMA_CONTROL1, value);
99 0 : }
100 :
101 0 : static void configure_regamma_mode(struct dce_transform *xfm_dce, uint32_t mode)
102 : {
103 0 : uint32_t value = 0;
104 :
105 0 : set_reg_field_value(
106 : value,
107 : mode,
108 : GAMMA_CORR_CONTROL,
109 : GAMMA_CORR_MODE);
110 :
111 0 : dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CONTROL, 0);
112 0 : }
113 :
114 : /*
115 : *****************************************************************************
116 : * Function: regamma_config_regions_and_segments
117 : *
118 : * build regamma curve by using predefined hw points
119 : * uses interface parameters ,like EDID coeff.
120 : *
121 : * @param : parameters interface parameters
122 : * @return void
123 : *
124 : * @note
125 : *
126 : * @see
127 : *
128 : *****************************************************************************
129 : */
130 0 : static void regamma_config_regions_and_segments(
131 : struct dce_transform *xfm_dce, const struct pwl_params *params)
132 : {
133 : const struct gamma_curve *curve;
134 0 : uint32_t value = 0;
135 :
136 : {
137 0 : set_reg_field_value(
138 : value,
139 : params->arr_points[0].custom_float_x,
140 : GAMMA_CORR_CNTLA_START_CNTL,
141 : GAMMA_CORR_CNTLA_EXP_REGION_START);
142 :
143 0 : set_reg_field_value(
144 : value,
145 : 0,
146 : GAMMA_CORR_CNTLA_START_CNTL,
147 : GAMMA_CORR_CNTLA_EXP_REGION_START_SEGMENT);
148 :
149 0 : dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CNTLA_START_CNTL,
150 : value);
151 : }
152 : {
153 0 : value = 0;
154 0 : set_reg_field_value(
155 : value,
156 : params->arr_points[0].custom_float_slope,
157 : GAMMA_CORR_CNTLA_SLOPE_CNTL,
158 : GAMMA_CORR_CNTLA_EXP_REGION_LINEAR_SLOPE);
159 :
160 0 : dm_write_reg(xfm_dce->base.ctx,
161 : mmGAMMA_CORR_CNTLA_SLOPE_CNTL, value);
162 : }
163 : {
164 0 : value = 0;
165 0 : set_reg_field_value(
166 : value,
167 : params->arr_points[1].custom_float_x,
168 : GAMMA_CORR_CNTLA_END_CNTL1,
169 : GAMMA_CORR_CNTLA_EXP_REGION_END);
170 :
171 0 : dm_write_reg(xfm_dce->base.ctx,
172 : mmGAMMA_CORR_CNTLA_END_CNTL1, value);
173 : }
174 : {
175 0 : value = 0;
176 0 : set_reg_field_value(
177 : value,
178 : params->arr_points[1].custom_float_slope,
179 : GAMMA_CORR_CNTLA_END_CNTL2,
180 : GAMMA_CORR_CNTLA_EXP_REGION_END_BASE);
181 :
182 0 : set_reg_field_value(
183 : value,
184 : params->arr_points[1].custom_float_y,
185 : GAMMA_CORR_CNTLA_END_CNTL2,
186 : GAMMA_CORR_CNTLA_EXP_REGION_END_SLOPE);
187 :
188 0 : dm_write_reg(xfm_dce->base.ctx,
189 : mmGAMMA_CORR_CNTLA_END_CNTL2, value);
190 : }
191 :
192 0 : curve = params->arr_curve_points;
193 :
194 : {
195 0 : value = 0;
196 0 : set_reg_field_value(
197 : value,
198 : curve[0].offset,
199 : GAMMA_CORR_CNTLA_REGION_0_1,
200 : GAMMA_CORR_CNTLA_EXP_REGION0_LUT_OFFSET);
201 :
202 0 : set_reg_field_value(
203 : value,
204 : curve[0].segments_num,
205 : GAMMA_CORR_CNTLA_REGION_0_1,
206 : GAMMA_CORR_CNTLA_EXP_REGION0_NUM_SEGMENTS);
207 :
208 0 : set_reg_field_value(
209 : value,
210 : curve[1].offset,
211 : GAMMA_CORR_CNTLA_REGION_0_1,
212 : GAMMA_CORR_CNTLA_EXP_REGION1_LUT_OFFSET);
213 :
214 0 : set_reg_field_value(
215 : value,
216 : curve[1].segments_num,
217 : GAMMA_CORR_CNTLA_REGION_0_1,
218 : GAMMA_CORR_CNTLA_EXP_REGION1_NUM_SEGMENTS);
219 :
220 0 : dm_write_reg(
221 : xfm_dce->base.ctx,
222 : mmGAMMA_CORR_CNTLA_REGION_0_1,
223 : value);
224 : }
225 :
226 0 : curve += 2;
227 : {
228 0 : value = 0;
229 0 : set_reg_field_value(
230 : value,
231 : curve[0].offset,
232 : GAMMA_CORR_CNTLA_REGION_2_3,
233 : GAMMA_CORR_CNTLA_EXP_REGION2_LUT_OFFSET);
234 :
235 0 : set_reg_field_value(
236 : value,
237 : curve[0].segments_num,
238 : GAMMA_CORR_CNTLA_REGION_2_3,
239 : GAMMA_CORR_CNTLA_EXP_REGION2_NUM_SEGMENTS);
240 :
241 0 : set_reg_field_value(
242 : value,
243 : curve[1].offset,
244 : GAMMA_CORR_CNTLA_REGION_2_3,
245 : GAMMA_CORR_CNTLA_EXP_REGION3_LUT_OFFSET);
246 :
247 0 : set_reg_field_value(
248 : value,
249 : curve[1].segments_num,
250 : GAMMA_CORR_CNTLA_REGION_2_3,
251 : GAMMA_CORR_CNTLA_EXP_REGION3_NUM_SEGMENTS);
252 :
253 0 : dm_write_reg(xfm_dce->base.ctx,
254 : mmGAMMA_CORR_CNTLA_REGION_2_3,
255 : value);
256 : }
257 :
258 0 : curve += 2;
259 : {
260 0 : value = 0;
261 0 : set_reg_field_value(
262 : value,
263 : curve[0].offset,
264 : GAMMA_CORR_CNTLA_REGION_4_5,
265 : GAMMA_CORR_CNTLA_EXP_REGION4_LUT_OFFSET);
266 :
267 0 : set_reg_field_value(
268 : value,
269 : curve[0].segments_num,
270 : GAMMA_CORR_CNTLA_REGION_4_5,
271 : GAMMA_CORR_CNTLA_EXP_REGION4_NUM_SEGMENTS);
272 :
273 0 : set_reg_field_value(
274 : value,
275 : curve[1].offset,
276 : GAMMA_CORR_CNTLA_REGION_4_5,
277 : GAMMA_CORR_CNTLA_EXP_REGION5_LUT_OFFSET);
278 :
279 0 : set_reg_field_value(
280 : value,
281 : curve[1].segments_num,
282 : GAMMA_CORR_CNTLA_REGION_4_5,
283 : GAMMA_CORR_CNTLA_EXP_REGION5_NUM_SEGMENTS);
284 :
285 0 : dm_write_reg(xfm_dce->base.ctx,
286 : mmGAMMA_CORR_CNTLA_REGION_4_5,
287 : value);
288 : }
289 :
290 0 : curve += 2;
291 : {
292 0 : value = 0;
293 0 : set_reg_field_value(
294 : value,
295 : curve[0].offset,
296 : GAMMA_CORR_CNTLA_REGION_6_7,
297 : GAMMA_CORR_CNTLA_EXP_REGION6_LUT_OFFSET);
298 :
299 0 : set_reg_field_value(
300 : value,
301 : curve[0].segments_num,
302 : GAMMA_CORR_CNTLA_REGION_6_7,
303 : GAMMA_CORR_CNTLA_EXP_REGION6_NUM_SEGMENTS);
304 :
305 0 : set_reg_field_value(
306 : value,
307 : curve[1].offset,
308 : GAMMA_CORR_CNTLA_REGION_6_7,
309 : GAMMA_CORR_CNTLA_EXP_REGION7_LUT_OFFSET);
310 :
311 0 : set_reg_field_value(
312 : value,
313 : curve[1].segments_num,
314 : GAMMA_CORR_CNTLA_REGION_6_7,
315 : GAMMA_CORR_CNTLA_EXP_REGION7_NUM_SEGMENTS);
316 :
317 0 : dm_write_reg(xfm_dce->base.ctx,
318 : mmGAMMA_CORR_CNTLA_REGION_6_7,
319 : value);
320 : }
321 :
322 0 : curve += 2;
323 : {
324 0 : value = 0;
325 0 : set_reg_field_value(
326 : value,
327 : curve[0].offset,
328 : GAMMA_CORR_CNTLA_REGION_8_9,
329 : GAMMA_CORR_CNTLA_EXP_REGION8_LUT_OFFSET);
330 :
331 0 : set_reg_field_value(
332 : value,
333 : curve[0].segments_num,
334 : GAMMA_CORR_CNTLA_REGION_8_9,
335 : GAMMA_CORR_CNTLA_EXP_REGION8_NUM_SEGMENTS);
336 :
337 0 : set_reg_field_value(
338 : value,
339 : curve[1].offset,
340 : GAMMA_CORR_CNTLA_REGION_8_9,
341 : GAMMA_CORR_CNTLA_EXP_REGION9_LUT_OFFSET);
342 :
343 0 : set_reg_field_value(
344 : value,
345 : curve[1].segments_num,
346 : GAMMA_CORR_CNTLA_REGION_8_9,
347 : GAMMA_CORR_CNTLA_EXP_REGION9_NUM_SEGMENTS);
348 :
349 0 : dm_write_reg(xfm_dce->base.ctx,
350 : mmGAMMA_CORR_CNTLA_REGION_8_9,
351 : value);
352 : }
353 :
354 0 : curve += 2;
355 : {
356 0 : value = 0;
357 0 : set_reg_field_value(
358 : value,
359 : curve[0].offset,
360 : GAMMA_CORR_CNTLA_REGION_10_11,
361 : GAMMA_CORR_CNTLA_EXP_REGION10_LUT_OFFSET);
362 :
363 0 : set_reg_field_value(
364 : value,
365 : curve[0].segments_num,
366 : GAMMA_CORR_CNTLA_REGION_10_11,
367 : GAMMA_CORR_CNTLA_EXP_REGION10_NUM_SEGMENTS);
368 :
369 0 : set_reg_field_value(
370 : value,
371 : curve[1].offset,
372 : GAMMA_CORR_CNTLA_REGION_10_11,
373 : GAMMA_CORR_CNTLA_EXP_REGION11_LUT_OFFSET);
374 :
375 0 : set_reg_field_value(
376 : value,
377 : curve[1].segments_num,
378 : GAMMA_CORR_CNTLA_REGION_10_11,
379 : GAMMA_CORR_CNTLA_EXP_REGION11_NUM_SEGMENTS);
380 :
381 0 : dm_write_reg(xfm_dce->base.ctx,
382 : mmGAMMA_CORR_CNTLA_REGION_10_11,
383 : value);
384 : }
385 :
386 0 : curve += 2;
387 : {
388 0 : value = 0;
389 0 : set_reg_field_value(
390 : value,
391 : curve[0].offset,
392 : GAMMA_CORR_CNTLA_REGION_12_13,
393 : GAMMA_CORR_CNTLA_EXP_REGION12_LUT_OFFSET);
394 :
395 0 : set_reg_field_value(
396 : value,
397 : curve[0].segments_num,
398 : GAMMA_CORR_CNTLA_REGION_12_13,
399 : GAMMA_CORR_CNTLA_EXP_REGION12_NUM_SEGMENTS);
400 :
401 0 : set_reg_field_value(
402 : value,
403 : curve[1].offset,
404 : GAMMA_CORR_CNTLA_REGION_12_13,
405 : GAMMA_CORR_CNTLA_EXP_REGION13_LUT_OFFSET);
406 :
407 0 : set_reg_field_value(
408 : value,
409 : curve[1].segments_num,
410 : GAMMA_CORR_CNTLA_REGION_12_13,
411 : GAMMA_CORR_CNTLA_EXP_REGION13_NUM_SEGMENTS);
412 :
413 0 : dm_write_reg(xfm_dce->base.ctx,
414 : mmGAMMA_CORR_CNTLA_REGION_12_13,
415 : value);
416 : }
417 :
418 0 : curve += 2;
419 : {
420 0 : value = 0;
421 0 : set_reg_field_value(
422 : value,
423 : curve[0].offset,
424 : GAMMA_CORR_CNTLA_REGION_14_15,
425 : GAMMA_CORR_CNTLA_EXP_REGION14_LUT_OFFSET);
426 :
427 0 : set_reg_field_value(
428 : value,
429 : curve[0].segments_num,
430 : GAMMA_CORR_CNTLA_REGION_14_15,
431 : GAMMA_CORR_CNTLA_EXP_REGION14_NUM_SEGMENTS);
432 :
433 0 : set_reg_field_value(
434 : value,
435 : curve[1].offset,
436 : GAMMA_CORR_CNTLA_REGION_14_15,
437 : GAMMA_CORR_CNTLA_EXP_REGION15_LUT_OFFSET);
438 :
439 0 : set_reg_field_value(
440 : value,
441 : curve[1].segments_num,
442 : GAMMA_CORR_CNTLA_REGION_14_15,
443 : GAMMA_CORR_CNTLA_EXP_REGION15_NUM_SEGMENTS);
444 :
445 0 : dm_write_reg(xfm_dce->base.ctx,
446 : mmGAMMA_CORR_CNTLA_REGION_14_15,
447 : value);
448 : }
449 0 : }
450 :
451 0 : static void program_pwl(struct dce_transform *xfm_dce,
452 : const struct pwl_params *params)
453 : {
454 0 : uint32_t value = 0;
455 :
456 0 : set_reg_field_value(
457 : value,
458 : 7,
459 : GAMMA_CORR_LUT_WRITE_EN_MASK,
460 : GAMMA_CORR_LUT_WRITE_EN_MASK);
461 :
462 0 : dm_write_reg(xfm_dce->base.ctx,
463 : mmGAMMA_CORR_LUT_WRITE_EN_MASK, value);
464 :
465 0 : dm_write_reg(xfm_dce->base.ctx,
466 : mmGAMMA_CORR_LUT_INDEX, 0);
467 :
468 : /* Program REGAMMA_LUT_DATA */
469 : {
470 0 : const uint32_t addr = mmGAMMA_CORR_LUT_DATA;
471 0 : uint32_t i = 0;
472 0 : const struct pwl_result_data *rgb =
473 : params->rgb_resulted;
474 :
475 0 : while (i != params->hw_points_num) {
476 0 : dm_write_reg(xfm_dce->base.ctx, addr, rgb->red_reg);
477 0 : dm_write_reg(xfm_dce->base.ctx, addr, rgb->green_reg);
478 0 : dm_write_reg(xfm_dce->base.ctx, addr, rgb->blue_reg);
479 :
480 0 : dm_write_reg(xfm_dce->base.ctx, addr,
481 : rgb->delta_red_reg);
482 0 : dm_write_reg(xfm_dce->base.ctx, addr,
483 : rgb->delta_green_reg);
484 0 : dm_write_reg(xfm_dce->base.ctx, addr,
485 : rgb->delta_blue_reg);
486 :
487 0 : ++rgb;
488 0 : ++i;
489 : }
490 : }
491 0 : }
492 :
493 0 : void dce110_opp_program_regamma_pwl_v(
494 : struct transform *xfm,
495 : const struct pwl_params *params)
496 : {
497 0 : struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
498 :
499 : /* Setup regions */
500 0 : regamma_config_regions_and_segments(xfm_dce, params);
501 :
502 0 : set_bypass_input_gamma(xfm_dce);
503 :
504 : /* Power on gamma LUT memory */
505 0 : power_on_lut(xfm, true, false, true);
506 :
507 : /* Program PWL */
508 0 : program_pwl(xfm_dce, params);
509 :
510 : /* program regamma config */
511 0 : configure_regamma_mode(xfm_dce, 1);
512 :
513 : /* Power return to auto back */
514 0 : power_on_lut(xfm, false, false, true);
515 0 : }
516 :
517 0 : void dce110_opp_power_on_regamma_lut_v(
518 : struct transform *xfm,
519 : bool power_on)
520 : {
521 0 : uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
522 :
523 0 : set_reg_field_value(
524 : value,
525 : 0,
526 : DCFEV_MEM_PWR_CTRL,
527 : COL_MAN_GAMMA_CORR_MEM_PWR_FORCE);
528 :
529 0 : set_reg_field_value(
530 : value,
531 : power_on,
532 : DCFEV_MEM_PWR_CTRL,
533 : COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
534 :
535 0 : set_reg_field_value(
536 : value,
537 : 0,
538 : DCFEV_MEM_PWR_CTRL,
539 : COL_MAN_INPUT_GAMMA_MEM_PWR_FORCE);
540 :
541 0 : set_reg_field_value(
542 : value,
543 : power_on,
544 : DCFEV_MEM_PWR_CTRL,
545 : COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
546 :
547 0 : dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
548 0 : }
549 :
550 0 : void dce110_opp_set_regamma_mode_v(
551 : struct transform *xfm,
552 : enum opp_regamma mode)
553 : {
554 : // TODO: need to implement the function
555 0 : }
|