xref: /openbmc/linux/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1  /*
2   * Copyright 2016 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 "core_types.h"
29  
30  #include "reg_helper.h"
31  #include "dcn10_dpp.h"
32  #include "basics/conversion.h"
33  
34  #define NUM_PHASES    64
35  #define HORZ_MAX_TAPS 8
36  #define VERT_MAX_TAPS 8
37  
38  #define BLACK_OFFSET_RGB_Y 0x0
39  #define BLACK_OFFSET_CBCR  0x8000
40  
41  #define REG(reg)\
42  	dpp->tf_regs->reg
43  
44  #define CTX \
45  	dpp->base.ctx
46  
47  #undef FN
48  #define FN(reg_name, field_name) \
49  	dpp->tf_shift->field_name, dpp->tf_mask->field_name
50  
51  enum pixel_format_description {
52  	PIXEL_FORMAT_FIXED = 0,
53  	PIXEL_FORMAT_FIXED16,
54  	PIXEL_FORMAT_FLOAT
55  
56  };
57  
58  enum dcn10_coef_filter_type_sel {
59  	SCL_COEF_LUMA_VERT_FILTER = 0,
60  	SCL_COEF_LUMA_HORZ_FILTER = 1,
61  	SCL_COEF_CHROMA_VERT_FILTER = 2,
62  	SCL_COEF_CHROMA_HORZ_FILTER = 3,
63  	SCL_COEF_ALPHA_VERT_FILTER = 4,
64  	SCL_COEF_ALPHA_HORZ_FILTER = 5
65  };
66  
67  enum dscl_autocal_mode {
68  	AUTOCAL_MODE_OFF = 0,
69  
70  	/* Autocal calculate the scaling ratio and initial phase and the
71  	 * DSCL_MODE_SEL must be set to 1
72  	 */
73  	AUTOCAL_MODE_AUTOSCALE = 1,
74  	/* Autocal perform auto centering without replication and the
75  	 * DSCL_MODE_SEL must be set to 0
76  	 */
77  	AUTOCAL_MODE_AUTOCENTER = 2,
78  	/* Autocal perform auto centering and auto replication and the
79  	 * DSCL_MODE_SEL must be set to 0
80  	 */
81  	AUTOCAL_MODE_AUTOREPLICATE = 3
82  };
83  
84  enum dscl_mode_sel {
85  	DSCL_MODE_SCALING_444_BYPASS = 0,
86  	DSCL_MODE_SCALING_444_RGB_ENABLE = 1,
87  	DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2,
88  	DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3,
89  	DSCL_MODE_SCALING_420_LUMA_BYPASS = 4,
90  	DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5,
91  	DSCL_MODE_DSCL_BYPASS = 6
92  };
93  
dpp_read_state(struct dpp * dpp_base,struct dcn_dpp_state * s)94  void dpp_read_state(struct dpp *dpp_base,
95  		struct dcn_dpp_state *s)
96  {
97  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
98  
99  	REG_GET(DPP_CONTROL,
100  			DPP_CLOCK_ENABLE, &s->is_enabled);
101  	REG_GET(CM_IGAM_CONTROL,
102  			CM_IGAM_LUT_MODE, &s->igam_lut_mode);
103  	REG_GET(CM_IGAM_CONTROL,
104  			CM_IGAM_INPUT_FORMAT, &s->igam_input_format);
105  	REG_GET(CM_DGAM_CONTROL,
106  			CM_DGAM_LUT_MODE, &s->dgam_lut_mode);
107  	REG_GET(CM_RGAM_CONTROL,
108  			CM_RGAM_LUT_MODE, &s->rgam_lut_mode);
109  	REG_GET(CM_GAMUT_REMAP_CONTROL,
110  			CM_GAMUT_REMAP_MODE, &s->gamut_remap_mode);
111  
112  	if (s->gamut_remap_mode) {
113  		s->gamut_remap_c11_c12 = REG_READ(CM_GAMUT_REMAP_C11_C12);
114  		s->gamut_remap_c13_c14 = REG_READ(CM_GAMUT_REMAP_C13_C14);
115  		s->gamut_remap_c21_c22 = REG_READ(CM_GAMUT_REMAP_C21_C22);
116  		s->gamut_remap_c23_c24 = REG_READ(CM_GAMUT_REMAP_C23_C24);
117  		s->gamut_remap_c31_c32 = REG_READ(CM_GAMUT_REMAP_C31_C32);
118  		s->gamut_remap_c33_c34 = REG_READ(CM_GAMUT_REMAP_C33_C34);
119  	}
120  }
121  
122  #define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19))
123  
dpp1_get_optimal_number_of_taps(struct dpp * dpp,struct scaler_data * scl_data,const struct scaling_taps * in_taps)124  bool dpp1_get_optimal_number_of_taps(
125  		struct dpp *dpp,
126  		struct scaler_data *scl_data,
127  		const struct scaling_taps *in_taps)
128  {
129  	/* Some ASICs does not support  FP16 scaling, so we reject modes require this*/
130  	if (scl_data->format == PIXEL_FORMAT_FP16 &&
131  		dpp->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT &&
132  		scl_data->ratios.horz.value != dc_fixpt_one.value &&
133  		scl_data->ratios.vert.value != dc_fixpt_one.value)
134  		return false;
135  
136  	if (scl_data->viewport.width > scl_data->h_active &&
137  		dpp->ctx->dc->debug.max_downscale_src_width != 0 &&
138  		scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width)
139  		return false;
140  
141  	/* TODO: add lb check */
142  
143  	/* No support for programming ratio of 4, drop to 3.99999.. */
144  	if (scl_data->ratios.horz.value == (4ll << 32))
145  		scl_data->ratios.horz.value--;
146  	if (scl_data->ratios.vert.value == (4ll << 32))
147  		scl_data->ratios.vert.value--;
148  	if (scl_data->ratios.horz_c.value == (4ll << 32))
149  		scl_data->ratios.horz_c.value--;
150  	if (scl_data->ratios.vert_c.value == (4ll << 32))
151  		scl_data->ratios.vert_c.value--;
152  
153  	/* Set default taps if none are provided */
154  	if (in_taps->h_taps == 0)
155  		scl_data->taps.h_taps = 4;
156  	else
157  		scl_data->taps.h_taps = in_taps->h_taps;
158  	if (in_taps->v_taps == 0)
159  		scl_data->taps.v_taps = 4;
160  	else
161  		scl_data->taps.v_taps = in_taps->v_taps;
162  	if (in_taps->v_taps_c == 0)
163  		scl_data->taps.v_taps_c = 2;
164  	else
165  		scl_data->taps.v_taps_c = in_taps->v_taps_c;
166  	if (in_taps->h_taps_c == 0)
167  		scl_data->taps.h_taps_c = 2;
168  	/* Only 1 and even h_taps_c are supported by hw */
169  	else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1)
170  		scl_data->taps.h_taps_c = in_taps->h_taps_c - 1;
171  	else
172  		scl_data->taps.h_taps_c = in_taps->h_taps_c;
173  
174  	if (!dpp->ctx->dc->debug.always_scale) {
175  		if (IDENTITY_RATIO(scl_data->ratios.horz))
176  			scl_data->taps.h_taps = 1;
177  		if (IDENTITY_RATIO(scl_data->ratios.vert))
178  			scl_data->taps.v_taps = 1;
179  		if (IDENTITY_RATIO(scl_data->ratios.horz_c))
180  			scl_data->taps.h_taps_c = 1;
181  		if (IDENTITY_RATIO(scl_data->ratios.vert_c))
182  			scl_data->taps.v_taps_c = 1;
183  	}
184  
185  	return true;
186  }
187  
dpp_reset(struct dpp * dpp_base)188  void dpp_reset(struct dpp *dpp_base)
189  {
190  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
191  
192  	dpp->filter_h_c = NULL;
193  	dpp->filter_v_c = NULL;
194  	dpp->filter_h = NULL;
195  	dpp->filter_v = NULL;
196  
197  	memset(&dpp->scl_data, 0, sizeof(dpp->scl_data));
198  	memset(&dpp->pwl_data, 0, sizeof(dpp->pwl_data));
199  }
200  
201  
202  
dpp1_cm_set_regamma_pwl(struct dpp * dpp_base,const struct pwl_params * params,enum opp_regamma mode)203  static void dpp1_cm_set_regamma_pwl(
204  	struct dpp *dpp_base, const struct pwl_params *params, enum opp_regamma mode)
205  {
206  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
207  	uint32_t re_mode = 0;
208  
209  	switch (mode) {
210  	case OPP_REGAMMA_BYPASS:
211  		re_mode = 0;
212  		break;
213  	case OPP_REGAMMA_SRGB:
214  		re_mode = 1;
215  		break;
216  	case OPP_REGAMMA_XVYCC:
217  		re_mode = 2;
218  		break;
219  	case OPP_REGAMMA_USER:
220  		re_mode = dpp->is_write_to_ram_a_safe ? 4 : 3;
221  		if (memcmp(&dpp->pwl_data, params, sizeof(*params)) == 0)
222  			break;
223  
224  		dpp1_cm_power_on_regamma_lut(dpp_base, true);
225  		dpp1_cm_configure_regamma_lut(dpp_base, dpp->is_write_to_ram_a_safe);
226  
227  		if (dpp->is_write_to_ram_a_safe)
228  			dpp1_cm_program_regamma_luta_settings(dpp_base, params);
229  		else
230  			dpp1_cm_program_regamma_lutb_settings(dpp_base, params);
231  
232  		dpp1_cm_program_regamma_lut(dpp_base, params->rgb_resulted,
233  					    params->hw_points_num);
234  		dpp->pwl_data = *params;
235  
236  		re_mode = dpp->is_write_to_ram_a_safe ? 3 : 4;
237  		dpp->is_write_to_ram_a_safe = !dpp->is_write_to_ram_a_safe;
238  		break;
239  	default:
240  		break;
241  	}
242  	REG_SET(CM_RGAM_CONTROL, 0, CM_RGAM_LUT_MODE, re_mode);
243  }
244  
dpp1_setup_format_flags(enum surface_pixel_format input_format,enum pixel_format_description * fmt)245  static void dpp1_setup_format_flags(enum surface_pixel_format input_format,\
246  						enum pixel_format_description *fmt)
247  {
248  
249  	if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F ||
250  		input_format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F)
251  		*fmt = PIXEL_FORMAT_FLOAT;
252  	else if (input_format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ||
253  		input_format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616)
254  		*fmt = PIXEL_FORMAT_FIXED16;
255  	else
256  		*fmt = PIXEL_FORMAT_FIXED;
257  }
258  
dpp1_set_degamma_format_float(struct dpp * dpp_base,bool is_float)259  static void dpp1_set_degamma_format_float(
260  		struct dpp *dpp_base,
261  		bool is_float)
262  {
263  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
264  
265  	if (is_float) {
266  		REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 3);
267  		REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, 1);
268  	} else {
269  		REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_INPUT_FORMAT, 2);
270  		REG_UPDATE(CM_IGAM_CONTROL, CM_IGAM_LUT_MODE, 0);
271  	}
272  }
273  
dpp1_cnv_setup(struct dpp * dpp_base,enum surface_pixel_format format,enum expansion_mode mode,struct dc_csc_transform input_csc_color_matrix,enum dc_color_space input_color_space,struct cnv_alpha_2bit_lut * alpha_2bit_lut)274  void dpp1_cnv_setup (
275  		struct dpp *dpp_base,
276  		enum surface_pixel_format format,
277  		enum expansion_mode mode,
278  		struct dc_csc_transform input_csc_color_matrix,
279  		enum dc_color_space input_color_space,
280  		struct cnv_alpha_2bit_lut *alpha_2bit_lut)
281  {
282  	uint32_t pixel_format;
283  	uint32_t alpha_en;
284  	enum pixel_format_description fmt ;
285  	enum dc_color_space color_space;
286  	enum dcn10_input_csc_select select;
287  	bool is_float;
288  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
289  	bool force_disable_cursor = false;
290  	struct out_csc_color_matrix tbl_entry;
291  	int i = 0;
292  
293  	dpp1_setup_format_flags(format, &fmt);
294  	alpha_en = 1;
295  	pixel_format = 0;
296  	color_space = COLOR_SPACE_SRGB;
297  	select = INPUT_CSC_SELECT_BYPASS;
298  	is_float = false;
299  
300  	switch (fmt) {
301  	case PIXEL_FORMAT_FIXED:
302  	case PIXEL_FORMAT_FIXED16:
303  	/*when output is float then FORMAT_CONTROL__OUTPUT_FP=1*/
304  		REG_SET_3(FORMAT_CONTROL, 0,
305  			CNVC_BYPASS, 0,
306  			FORMAT_EXPANSION_MODE, mode,
307  			OUTPUT_FP, 0);
308  		break;
309  	case PIXEL_FORMAT_FLOAT:
310  		REG_SET_3(FORMAT_CONTROL, 0,
311  			CNVC_BYPASS, 0,
312  			FORMAT_EXPANSION_MODE, mode,
313  			OUTPUT_FP, 1);
314  		is_float = true;
315  		break;
316  	default:
317  
318  		break;
319  	}
320  
321  	dpp1_set_degamma_format_float(dpp_base, is_float);
322  
323  	switch (format) {
324  	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
325  		pixel_format = 1;
326  		break;
327  	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
328  		pixel_format = 3;
329  		alpha_en = 0;
330  		break;
331  	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
332  	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
333  		pixel_format = 8;
334  		break;
335  	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
336  	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
337  		pixel_format = 10;
338  		break;
339  	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
340  		force_disable_cursor = false;
341  		pixel_format = 65;
342  		color_space = COLOR_SPACE_YCBCR709;
343  		select = INPUT_CSC_SELECT_ICSC;
344  		break;
345  	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
346  		force_disable_cursor = true;
347  		pixel_format = 64;
348  		color_space = COLOR_SPACE_YCBCR709;
349  		select = INPUT_CSC_SELECT_ICSC;
350  		break;
351  	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
352  		force_disable_cursor = true;
353  		pixel_format = 67;
354  		color_space = COLOR_SPACE_YCBCR709;
355  		select = INPUT_CSC_SELECT_ICSC;
356  		break;
357  	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
358  		force_disable_cursor = true;
359  		pixel_format = 66;
360  		color_space = COLOR_SPACE_YCBCR709;
361  		select = INPUT_CSC_SELECT_ICSC;
362  		break;
363  	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
364  	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
365  		pixel_format = 26; /* ARGB16161616_UNORM */
366  		break;
367  	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
368  		pixel_format = 24;
369  		break;
370  	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
371  		pixel_format = 25;
372  		break;
373  	default:
374  		break;
375  	}
376  
377  	/* Set default color space based on format if none is given. */
378  	color_space = input_color_space ? input_color_space : color_space;
379  
380  	REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0,
381  			CNVC_SURFACE_PIXEL_FORMAT, pixel_format);
382  	REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
383  
384  	// if input adjustments exist, program icsc with those values
385  
386  	if (input_csc_color_matrix.enable_adjustment
387  				== true) {
388  		for (i = 0; i < 12; i++)
389  			tbl_entry.regval[i] = input_csc_color_matrix.matrix[i];
390  
391  		tbl_entry.color_space = color_space;
392  
393  		if (color_space >= COLOR_SPACE_YCBCR601)
394  			select = INPUT_CSC_SELECT_ICSC;
395  		else
396  			select = INPUT_CSC_SELECT_BYPASS;
397  
398  		dpp1_program_input_csc(dpp_base, color_space, select, &tbl_entry);
399  	} else
400  		dpp1_program_input_csc(dpp_base, color_space, select, NULL);
401  
402  	if (force_disable_cursor) {
403  		REG_UPDATE(CURSOR_CONTROL,
404  				CURSOR_ENABLE, 0);
405  		REG_UPDATE(CURSOR0_CONTROL,
406  				CUR0_ENABLE, 0);
407  	}
408  }
409  
dpp1_set_cursor_attributes(struct dpp * dpp_base,struct dc_cursor_attributes * cursor_attributes)410  void dpp1_set_cursor_attributes(
411  		struct dpp *dpp_base,
412  		struct dc_cursor_attributes *cursor_attributes)
413  {
414  	enum dc_cursor_color_format color_format = cursor_attributes->color_format;
415  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
416  
417  	REG_UPDATE_2(CURSOR0_CONTROL,
418  			CUR0_MODE, color_format,
419  			CUR0_EXPANSION_MODE, 0);
420  
421  	if (color_format == CURSOR_MODE_MONO) {
422  		/* todo: clarify what to program these to */
423  		REG_UPDATE(CURSOR0_COLOR0,
424  				CUR0_COLOR0, 0x00000000);
425  		REG_UPDATE(CURSOR0_COLOR1,
426  				CUR0_COLOR1, 0xFFFFFFFF);
427  	}
428  }
429  
430  
dpp1_set_cursor_position(struct dpp * dpp_base,const struct dc_cursor_position * pos,const struct dc_cursor_mi_param * param,uint32_t width,uint32_t height)431  void dpp1_set_cursor_position(
432  		struct dpp *dpp_base,
433  		const struct dc_cursor_position *pos,
434  		const struct dc_cursor_mi_param *param,
435  		uint32_t width,
436  		uint32_t height)
437  {
438  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
439  	int x_pos = pos->x - param->viewport.x;
440  	int y_pos = pos->y - param->viewport.y;
441  	int x_hotspot = pos->x_hotspot;
442  	int y_hotspot = pos->y_hotspot;
443  	int src_x_offset = x_pos - pos->x_hotspot;
444  	int src_y_offset = y_pos - pos->y_hotspot;
445  	int cursor_height = (int)height;
446  	int cursor_width = (int)width;
447  	uint32_t cur_en = pos->enable ? 1 : 0;
448  
449  	// Transform cursor width / height and hotspots for offset calculations
450  	if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) {
451  		swap(cursor_height, cursor_width);
452  		swap(x_hotspot, y_hotspot);
453  
454  		if (param->rotation == ROTATION_ANGLE_90) {
455  			// hotspot = (-y, x)
456  			src_x_offset = x_pos - (cursor_width - x_hotspot);
457  			src_y_offset = y_pos - y_hotspot;
458  		} else if (param->rotation == ROTATION_ANGLE_270) {
459  			// hotspot = (y, -x)
460  			src_x_offset = x_pos - x_hotspot;
461  			src_y_offset = y_pos - (cursor_height - y_hotspot);
462  		}
463  	} else if (param->rotation == ROTATION_ANGLE_180) {
464  		// hotspot = (-x, -y)
465  		if (!param->mirror)
466  			src_x_offset = x_pos - (cursor_width - x_hotspot);
467  
468  		src_y_offset = y_pos - (cursor_height - y_hotspot);
469  	}
470  
471  	if (src_x_offset >= (int)param->viewport.width)
472  		cur_en = 0;  /* not visible beyond right edge*/
473  
474  	if (src_x_offset + cursor_width <= 0)
475  		cur_en = 0;  /* not visible beyond left edge*/
476  
477  	if (src_y_offset >= (int)param->viewport.height)
478  		cur_en = 0;  /* not visible beyond bottom edge*/
479  
480  	if (src_y_offset + cursor_height <= 0)
481  		cur_en = 0;  /* not visible beyond top edge*/
482  
483  	REG_UPDATE(CURSOR0_CONTROL,
484  			CUR0_ENABLE, cur_en);
485  
486  	dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
487  }
488  
dpp1_cnv_set_optional_cursor_attributes(struct dpp * dpp_base,struct dpp_cursor_attributes * attr)489  void dpp1_cnv_set_optional_cursor_attributes(
490  		struct dpp *dpp_base,
491  		struct dpp_cursor_attributes *attr)
492  {
493  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
494  
495  	if (attr) {
496  		REG_UPDATE(CURSOR0_FP_SCALE_BIAS,  CUR0_FP_BIAS,  attr->bias);
497  		REG_UPDATE(CURSOR0_FP_SCALE_BIAS,  CUR0_FP_SCALE, attr->scale);
498  	}
499  }
500  
dpp1_dppclk_control(struct dpp * dpp_base,bool dppclk_div,bool enable)501  void dpp1_dppclk_control(
502  		struct dpp *dpp_base,
503  		bool dppclk_div,
504  		bool enable)
505  {
506  	struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
507  
508  	if (enable) {
509  		if (dpp->tf_mask->DPPCLK_RATE_CONTROL)
510  			REG_UPDATE_2(DPP_CONTROL,
511  				DPPCLK_RATE_CONTROL, dppclk_div,
512  				DPP_CLOCK_ENABLE, 1);
513  		else
514  			REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 1);
515  	} else
516  		REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 0);
517  }
518  
519  static const struct dpp_funcs dcn10_dpp_funcs = {
520  		.dpp_read_state = dpp_read_state,
521  		.dpp_reset = dpp_reset,
522  		.dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale,
523  		.dpp_get_optimal_number_of_taps = dpp1_get_optimal_number_of_taps,
524  		.dpp_set_gamut_remap = dpp1_cm_set_gamut_remap,
525  		.dpp_set_csc_adjustment = dpp1_cm_set_output_csc_adjustment,
526  		.dpp_set_csc_default = dpp1_cm_set_output_csc_default,
527  		.dpp_power_on_regamma_lut = dpp1_cm_power_on_regamma_lut,
528  		.dpp_program_regamma_lut = dpp1_cm_program_regamma_lut,
529  		.dpp_configure_regamma_lut = dpp1_cm_configure_regamma_lut,
530  		.dpp_program_regamma_lutb_settings = dpp1_cm_program_regamma_lutb_settings,
531  		.dpp_program_regamma_luta_settings = dpp1_cm_program_regamma_luta_settings,
532  		.dpp_program_regamma_pwl = dpp1_cm_set_regamma_pwl,
533  		.dpp_program_bias_and_scale = dpp1_program_bias_and_scale,
534  		.dpp_set_degamma = dpp1_set_degamma,
535  		.dpp_program_input_lut		= dpp1_program_input_lut,
536  		.dpp_program_degamma_pwl	= dpp1_set_degamma_pwl,
537  		.dpp_setup			= dpp1_cnv_setup,
538  		.dpp_full_bypass		= dpp1_full_bypass,
539  		.set_cursor_attributes = dpp1_set_cursor_attributes,
540  		.set_cursor_position = dpp1_set_cursor_position,
541  		.set_optional_cursor_attributes = dpp1_cnv_set_optional_cursor_attributes,
542  		.dpp_dppclk_control = dpp1_dppclk_control,
543  		.dpp_set_hdr_multiplier = dpp1_set_hdr_multiplier,
544  		.dpp_program_blnd_lut = NULL,
545  		.dpp_program_shaper_lut = NULL,
546  		.dpp_program_3dlut = NULL
547  };
548  
549  static struct dpp_caps dcn10_dpp_cap = {
550  	.dscl_data_proc_format = DSCL_DATA_PRCESSING_FIXED_FORMAT,
551  	.dscl_calc_lb_num_partitions = dpp1_dscl_calc_lb_num_partitions,
552  };
553  
554  /*****************************************/
555  /* Constructor, Destructor               */
556  /*****************************************/
557  
dpp1_construct(struct dcn10_dpp * dpp,struct dc_context * ctx,uint32_t inst,const struct dcn_dpp_registers * tf_regs,const struct dcn_dpp_shift * tf_shift,const struct dcn_dpp_mask * tf_mask)558  void dpp1_construct(
559  	struct dcn10_dpp *dpp,
560  	struct dc_context *ctx,
561  	uint32_t inst,
562  	const struct dcn_dpp_registers *tf_regs,
563  	const struct dcn_dpp_shift *tf_shift,
564  	const struct dcn_dpp_mask *tf_mask)
565  {
566  	dpp->base.ctx = ctx;
567  
568  	dpp->base.inst = inst;
569  	dpp->base.funcs = &dcn10_dpp_funcs;
570  	dpp->base.caps = &dcn10_dpp_cap;
571  
572  	dpp->tf_regs = tf_regs;
573  	dpp->tf_shift = tf_shift;
574  	dpp->tf_mask = tf_mask;
575  
576  	dpp->lb_pixel_depth_supported =
577  		LB_PIXEL_DEPTH_18BPP |
578  		LB_PIXEL_DEPTH_24BPP |
579  		LB_PIXEL_DEPTH_30BPP |
580  		LB_PIXEL_DEPTH_36BPP;
581  
582  	dpp->lb_bits_per_entry = LB_BITS_PER_ENTRY;
583  	dpp->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x1404*/
584  }
585