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 | |
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 | |
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 | |
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 | |
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(p: &dpp->pwl_data, q: params, size: sizeof(*params)) == 0) |
222 | break; |
223 | |
224 | dpp1_cm_power_on_regamma_lut(dpp_base, power_on: true); |
225 | dpp1_cm_configure_regamma_lut(dpp_base, is_ram_a: 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, rgb: params->rgb_resulted, |
233 | num: 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 | |
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 | |
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 | |
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(input_format: format, fmt: &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: &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 | |
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 | |
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 | |
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 | |
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 | |
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 | |