File Index
Files and directories
Sign in
FILE

dce110_opp_regamma_v.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_regamma_v.c C
  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
 34static void power_on_lut(struct transform *xfm,
 35	bool power_on, bool inputgamma, bool regamma)
 36{
 37	uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
 38	int i;
 39
 40	if (power_on) {
 41		if (inputgamma)
 42			set_reg_field_value(
 43				value,
 44				1,
 45				DCFEV_MEM_PWR_CTRL,
 46				COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
 47		if (regamma)
 48			set_reg_field_value(
 49				value,
 50				1,
 51				DCFEV_MEM_PWR_CTRL,
 52				COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
 53	} else {
 54		if (inputgamma)
 55			set_reg_field_value(
 56				value,
 57				0,
 58				DCFEV_MEM_PWR_CTRL,
 59				COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
 60		if (regamma)
 61			set_reg_field_value(
 62				value,
 63				0,
 64				DCFEV_MEM_PWR_CTRL,
 65				COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
 66	}
 67
 68	dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
 69
 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,
 73				DCFEV_MEM_PWR_CTRL,
 74				COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) &&
 75			get_reg_field_value(value,
 76					DCFEV_MEM_PWR_CTRL,
 77					COL_MAN_GAMMA_CORR_MEM_PWR_DIS))
 78			break;
 79
 80		udelay(2);
 81	}
 82}
 83
 84static void set_bypass_input_gamma(struct dce_transform *xfm_dce)
 85{
 86	uint32_t value;
 87
 88	value = dm_read_reg(xfm_dce->base.ctx,
 89			mmCOL_MAN_INPUT_GAMMA_CONTROL1);
 90
 91	set_reg_field_value(
 92				value,
 93				0,
 94				COL_MAN_INPUT_GAMMA_CONTROL1,
 95				INPUT_GAMMA_MODE);
 96
 97	dm_write_reg(xfm_dce->base.ctx,
 98			mmCOL_MAN_INPUT_GAMMA_CONTROL1, value);
 99}
100
101static void configure_regamma_mode(struct dce_transform *xfm_dce, uint32_t mode)
102{
103	uint32_t value = 0;
104
105	set_reg_field_value(
106				value,
107				mode,
108				GAMMA_CORR_CONTROL,
109				GAMMA_CORR_MODE);
110
111	dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CONTROL, 0);
112}
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 */
130static 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	uint32_t value = 0;
135
136	{
137		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		set_reg_field_value(
144			value,
145			0,
146			GAMMA_CORR_CNTLA_START_CNTL,
147			GAMMA_CORR_CNTLA_EXP_REGION_START_SEGMENT);
148
149		dm_write_reg(xfm_dce->base.ctx, mmGAMMA_CORR_CNTLA_START_CNTL,
150				value);
151	}
152	{
153		value = 0;
154		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		dm_write_reg(xfm_dce->base.ctx,
161			mmGAMMA_CORR_CNTLA_SLOPE_CNTL, value);
162	}
163	{
164		value = 0;
165		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		dm_write_reg(xfm_dce->base.ctx,
172			mmGAMMA_CORR_CNTLA_END_CNTL1, value);
173	}
174	{
175		value = 0;
176		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		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		dm_write_reg(xfm_dce->base.ctx,
189			mmGAMMA_CORR_CNTLA_END_CNTL2, value);
190	}
191
192	curve = params->arr_curve_points;
193
194	{
195		value = 0;
196		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		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		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		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		dm_write_reg(
221				xfm_dce->base.ctx,
222			mmGAMMA_CORR_CNTLA_REGION_0_1,
223			value);
224	}
225
226	curve += 2;
227	{
228		value = 0;
229		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		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		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		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		dm_write_reg(xfm_dce->base.ctx,
254			mmGAMMA_CORR_CNTLA_REGION_2_3,
255			value);
256	}
257
258	curve += 2;
259	{
260		value = 0;
261		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		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		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		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		dm_write_reg(xfm_dce->base.ctx,
286			mmGAMMA_CORR_CNTLA_REGION_4_5,
287			value);
288	}
289
290	curve += 2;
291	{
292		value = 0;
293		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		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		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		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		dm_write_reg(xfm_dce->base.ctx,
318			mmGAMMA_CORR_CNTLA_REGION_6_7,
319			value);
320	}
321
322	curve += 2;
323	{
324		value = 0;
325		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		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		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		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		dm_write_reg(xfm_dce->base.ctx,
350			mmGAMMA_CORR_CNTLA_REGION_8_9,
351			value);
352	}
353
354	curve += 2;
355	{
356		value = 0;
357		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		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		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		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		dm_write_reg(xfm_dce->base.ctx,
382			mmGAMMA_CORR_CNTLA_REGION_10_11,
383			value);
384	}
385
386	curve += 2;
387	{
388		value = 0;
389		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		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		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		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		dm_write_reg(xfm_dce->base.ctx,
414			mmGAMMA_CORR_CNTLA_REGION_12_13,
415			value);
416	}
417
418	curve += 2;
419	{
420		value = 0;
421		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		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		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		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		dm_write_reg(xfm_dce->base.ctx,
446			mmGAMMA_CORR_CNTLA_REGION_14_15,
447			value);
448	}
449}
450
451static void program_pwl(struct dce_transform *xfm_dce,
452		const struct pwl_params *params)
453{
454	uint32_t value = 0;
455
456	set_reg_field_value(
457		value,
458		7,
459		GAMMA_CORR_LUT_WRITE_EN_MASK,
460		GAMMA_CORR_LUT_WRITE_EN_MASK);
461
462	dm_write_reg(xfm_dce->base.ctx,
463		mmGAMMA_CORR_LUT_WRITE_EN_MASK, value);
464
465	dm_write_reg(xfm_dce->base.ctx,
466		mmGAMMA_CORR_LUT_INDEX, 0);
467
468	/* Program REGAMMA_LUT_DATA */
469	{
470		const uint32_t addr = mmGAMMA_CORR_LUT_DATA;
471		uint32_t i = 0;
472		const struct pwl_result_data *rgb =
473				params->rgb_resulted;
474
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);
479
480			dm_write_reg(xfm_dce->base.ctx, addr,
481				rgb->delta_red_reg);
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);
486
487			++rgb;
488			++i;
489		}
490	}
491}
492
493void dce110_opp_program_regamma_pwl_v(
494	struct transform *xfm,
495	const struct pwl_params *params)
496{
497	struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
498
499	/* Setup regions */
500	regamma_config_regions_and_segments(xfm_dce, params);
501
502	set_bypass_input_gamma(xfm_dce);
503
504	/* Power on gamma LUT memory */
505	power_on_lut(xfm, true, false, true);
506
507	/* Program PWL */
508	program_pwl(xfm_dce, params);
509
510	/* program regamma config */
511	configure_regamma_mode(xfm_dce, 1);
512
513	/* Power return to auto back */
514	power_on_lut(xfm, false, false, true);
515}
516
517void dce110_opp_power_on_regamma_lut_v(
518	struct transform *xfm,
519	bool power_on)
520{
521	uint32_t value = dm_read_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL);
522
523	set_reg_field_value(
524		value,
525		0,
526		DCFEV_MEM_PWR_CTRL,
527		COL_MAN_GAMMA_CORR_MEM_PWR_FORCE);
528
529	set_reg_field_value(
530		value,
531		power_on,
532		DCFEV_MEM_PWR_CTRL,
533		COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
534
535	set_reg_field_value(
536		value,
537		0,
538		DCFEV_MEM_PWR_CTRL,
539		COL_MAN_INPUT_GAMMA_MEM_PWR_FORCE);
540
541	set_reg_field_value(
542		value,
543		power_on,
544		DCFEV_MEM_PWR_CTRL,
545		COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
546
547	dm_write_reg(xfm->ctx, mmDCFEV_MEM_PWR_CTRL, value);
548}
549
550void dce110_opp_set_regamma_mode_v(
551	struct transform *xfm,
552	enum opp_regamma mode)
553{
554	// TODO: need to implement the function
555}
~/ Read-only file preview.