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 "dcn401/dcn401_dpp.h"
32 #include "basics/conversion.h"
33
34
35 #define NUM_PHASES 64
36 #define HORZ_MAX_TAPS 8
37 #define VERT_MAX_TAPS 8
38 #define NUM_LEVELS 32
39 #define BLACK_OFFSET_RGB_Y 0x0
40 #define BLACK_OFFSET_CBCR 0x8000
41
42
43 #define REG(reg)\
44 dpp->tf_regs->reg
45
46 #define CTX \
47 dpp->base.ctx
48
49 #undef FN
50 #define FN(reg_name, field_name) \
51 dpp->tf_shift->field_name, dpp->tf_mask->field_name
52
53 enum dcn401_coef_filter_type_sel {
54 SCL_COEF_LUMA_VERT_FILTER = 0,
55 SCL_COEF_LUMA_HORZ_FILTER = 1,
56 SCL_COEF_CHROMA_VERT_FILTER = 2,
57 SCL_COEF_CHROMA_HORZ_FILTER = 3,
58 SCL_COEF_ALPHA_VERT_FILTER = 4,
59 SCL_COEF_ALPHA_HORZ_FILTER = 5,
60 SCL_COEF_VERTICAL_BLUR_SCALE = SCL_COEF_ALPHA_VERT_FILTER,
61 SCL_COEF_HORIZONTAL_BLUR_SCALE = SCL_COEF_ALPHA_HORZ_FILTER
62 };
63
64 enum dscl_autocal_mode {
65 AUTOCAL_MODE_OFF = 0,
66
67 /* Autocal calculate the scaling ratio and initial phase and the
68 * DSCL_MODE_SEL must be set to 1
69 */
70 AUTOCAL_MODE_AUTOSCALE = 1,
71 /* Autocal perform auto centering without replication and the
72 * DSCL_MODE_SEL must be set to 0
73 */
74 AUTOCAL_MODE_AUTOCENTER = 2,
75 /* Autocal perform auto centering and auto replication and the
76 * DSCL_MODE_SEL must be set to 0
77 */
78 AUTOCAL_MODE_AUTOREPLICATE = 3
79 };
80
81 enum dscl_mode_sel {
82 DSCL_MODE_SCALING_444_BYPASS = 0,
83 DSCL_MODE_SCALING_444_RGB_ENABLE = 1,
84 DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2,
85 DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3,
86 DSCL_MODE_SCALING_420_LUMA_BYPASS = 4,
87 DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5,
88 DSCL_MODE_DSCL_BYPASS = 6
89 };
90
dpp401_dscl_get_pixel_depth_val(enum lb_pixel_depth depth)91 static int dpp401_dscl_get_pixel_depth_val(enum lb_pixel_depth depth)
92 {
93 if (depth == LB_PIXEL_DEPTH_30BPP)
94 return 0; /* 10 bpc */
95 else if (depth == LB_PIXEL_DEPTH_24BPP)
96 return 1; /* 8 bpc */
97 else if (depth == LB_PIXEL_DEPTH_18BPP)
98 return 2; /* 6 bpc */
99 else if (depth == LB_PIXEL_DEPTH_36BPP)
100 return 3; /* 12 bpc */
101 else {
102 ASSERT(0);
103 return -1; /* Unsupported */
104 }
105 }
106
dpp401_dscl_is_video_format(enum pixel_format format)107 static bool dpp401_dscl_is_video_format(enum pixel_format format)
108 {
109 if (format >= PIXEL_FORMAT_VIDEO_BEGIN
110 && format <= PIXEL_FORMAT_VIDEO_END)
111 return true;
112 else
113 return false;
114 }
115
dpp401_dscl_is_420_format(enum pixel_format format)116 static bool dpp401_dscl_is_420_format(enum pixel_format format)
117 {
118 if (format == PIXEL_FORMAT_420BPP8 ||
119 format == PIXEL_FORMAT_420BPP10)
120 return true;
121 else
122 return false;
123 }
124
dpp401_dscl_get_dscl_mode(struct dpp * dpp_base,const struct scaler_data * data,bool dbg_always_scale)125 static enum dscl_mode_sel dpp401_dscl_get_dscl_mode(
126 struct dpp *dpp_base,
127 const struct scaler_data *data,
128 bool dbg_always_scale)
129 {
130 const long long one = dc_fixpt_one.value;
131
132 if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
133 /* DSCL is processing data in fixed format */
134 if (data->format == PIXEL_FORMAT_FP16)
135 return DSCL_MODE_DSCL_BYPASS;
136 }
137
138 if (data->ratios.horz.value == one
139 && data->ratios.vert.value == one
140 && data->ratios.horz_c.value == one
141 && data->ratios.vert_c.value == one
142 && !dbg_always_scale)
143 return DSCL_MODE_SCALING_444_BYPASS;
144
145 if (!dpp401_dscl_is_420_format(data->format)) {
146 if (dpp401_dscl_is_video_format(data->format))
147 return DSCL_MODE_SCALING_444_YCBCR_ENABLE;
148 else
149 return DSCL_MODE_SCALING_444_RGB_ENABLE;
150 }
151 if (data->ratios.horz.value == one && data->ratios.vert.value == one)
152 return DSCL_MODE_SCALING_420_LUMA_BYPASS;
153 if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one)
154 return DSCL_MODE_SCALING_420_CHROMA_BYPASS;
155
156 return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
157 }
158
dpp401_power_on_dscl(struct dpp * dpp_base,bool power_on)159 static void dpp401_power_on_dscl(
160 struct dpp *dpp_base,
161 bool power_on)
162 {
163 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
164
165 if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) {
166 if (power_on) {
167 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 0);
168 REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5);
169 } else {
170 if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.dscl) {
171 dpp->base.ctx->dc->optimized_required = true;
172 dpp->base.deferred_reg_writes.bits.disable_dscl = true;
173 } else {
174 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
175 }
176 }
177 }
178 }
179
180
dpp401_dscl_set_lb(struct dcn401_dpp * dpp,const struct line_buffer_params * lb_params,enum lb_memory_config mem_size_config)181 static void dpp401_dscl_set_lb(
182 struct dcn401_dpp *dpp,
183 const struct line_buffer_params *lb_params,
184 enum lb_memory_config mem_size_config)
185 {
186 uint32_t max_partitions = 63; /* Currently hardcoded on all ASICs before DCN 3.2 */
187
188 /* LB */
189 if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
190 /* DSCL caps: pixel data processed in fixed format */
191 uint32_t pixel_depth = dpp401_dscl_get_pixel_depth_val(lb_params->depth);
192 uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
193
194 REG_SET_7(LB_DATA_FORMAT, 0,
195 PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */
196 PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */
197 PIXEL_REDUCE_MODE, 1, /* Pixel reduction mode: Rounding */
198 DYNAMIC_PIXEL_DEPTH, dyn_pix_depth, /* Dynamic expansion pixel depth */
199 DITHER_EN, 0, /* Dithering enable: Disabled */
200 INTERLEAVE_EN, lb_params->interleave_en, /* Interleave source enable */
201 LB_DATA_FORMAT__ALPHA_EN, lb_params->alpha_en); /* Alpha enable */
202 } else {
203 /* DSCL caps: pixel data processed in float format */
204 REG_SET_2(LB_DATA_FORMAT, 0,
205 INTERLEAVE_EN, lb_params->interleave_en, /* Interleave source enable */
206 LB_DATA_FORMAT__ALPHA_EN, lb_params->alpha_en); /* Alpha enable */
207 }
208
209 if (dpp->base.caps->max_lb_partitions == 31)
210 max_partitions = 31;
211
212 REG_SET_2(LB_MEMORY_CTRL, 0,
213 MEMORY_CONFIG, mem_size_config,
214 LB_MAX_PARTITIONS, max_partitions);
215 }
216
dpp401_dscl_get_filter_coeffs_64p(int taps,struct fixed31_32 ratio)217 static const uint16_t *dpp401_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
218 {
219 if (taps == 8)
220 return get_filter_8tap_64p(ratio);
221 else if (taps == 7)
222 return get_filter_7tap_64p(ratio);
223 else if (taps == 6)
224 return get_filter_6tap_64p(ratio);
225 else if (taps == 5)
226 return get_filter_5tap_64p(ratio);
227 else if (taps == 4)
228 return get_filter_4tap_64p(ratio);
229 else if (taps == 3)
230 return get_filter_3tap_64p(ratio);
231 else if (taps == 2)
232 return get_filter_2tap_64p();
233 else if (taps == 1)
234 return NULL;
235 else {
236 /* should never happen, bug */
237 BREAK_TO_DEBUGGER();
238 return NULL;
239 }
240 }
241
dpp401_dscl_set_scaler_filter(struct dcn401_dpp * dpp,uint32_t taps,enum dcn401_coef_filter_type_sel filter_type,const uint16_t * filter)242 static void dpp401_dscl_set_scaler_filter(
243 struct dcn401_dpp *dpp,
244 uint32_t taps,
245 enum dcn401_coef_filter_type_sel filter_type,
246 const uint16_t *filter)
247 {
248 const int tap_pairs = (taps + 1) / 2;
249 int phase;
250 int pair;
251 uint16_t odd_coef, even_coef;
252
253 REG_SET_3(SCL_COEF_RAM_TAP_SELECT, 0,
254 SCL_COEF_RAM_TAP_PAIR_IDX, 0,
255 SCL_COEF_RAM_PHASE, 0,
256 SCL_COEF_RAM_FILTER_TYPE, filter_type);
257
258 for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) {
259 for (pair = 0; pair < tap_pairs; pair++) {
260 even_coef = filter[phase * taps + 2 * pair];
261 if ((pair * 2 + 1) < taps)
262 odd_coef = filter[phase * taps + 2 * pair + 1];
263 else
264 odd_coef = 0;
265
266 REG_SET_4(SCL_COEF_RAM_TAP_DATA, 0,
267 /* Even tap coefficient (bits 1:0 fixed to 0) */
268 SCL_COEF_RAM_EVEN_TAP_COEF, even_coef,
269 /* Write/read control for even coefficient */
270 SCL_COEF_RAM_EVEN_TAP_COEF_EN, 1,
271 /* Odd tap coefficient (bits 1:0 fixed to 0) */
272 SCL_COEF_RAM_ODD_TAP_COEF, odd_coef,
273 /* Write/read control for odd coefficient */
274 SCL_COEF_RAM_ODD_TAP_COEF_EN, 1);
275 }
276 }
277
278 }
279
dpp401_dscl_set_scl_filter(struct dcn401_dpp * dpp,const struct scaler_data * scl_data,bool chroma_coef_mode,bool force_coeffs_update)280 static void dpp401_dscl_set_scl_filter(
281 struct dcn401_dpp *dpp,
282 const struct scaler_data *scl_data,
283 bool chroma_coef_mode,
284 bool force_coeffs_update)
285 {
286 bool h_2tap_hardcode_coef_en = false;
287 bool v_2tap_hardcode_coef_en = false;
288 bool h_2tap_sharp_en = false;
289 bool v_2tap_sharp_en = false;
290 uint32_t h_2tap_sharp_factor = scl_data->sharpness.horz;
291 uint32_t v_2tap_sharp_factor = scl_data->sharpness.vert;
292 bool coef_ram_current;
293 const uint16_t *filter_h = NULL;
294 const uint16_t *filter_v = NULL;
295 const uint16_t *filter_h_c = NULL;
296 const uint16_t *filter_v_c = NULL;
297
298 if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
299 filter_h = scl_data->dscl_prog_data.filter_h;
300 filter_v = scl_data->dscl_prog_data.filter_v;
301 if (chroma_coef_mode) {
302 filter_h_c = scl_data->dscl_prog_data.filter_h_c;
303 filter_v_c = scl_data->dscl_prog_data.filter_v_c;
304 }
305 } else {
306 filter_h = dpp401_dscl_get_filter_coeffs_64p(
307 scl_data->taps.h_taps, scl_data->ratios.horz);
308 filter_v = dpp401_dscl_get_filter_coeffs_64p(
309 scl_data->taps.v_taps, scl_data->ratios.vert);
310 if (chroma_coef_mode) {
311 filter_h_c = dpp401_dscl_get_filter_coeffs_64p(
312 scl_data->taps.h_taps_c, scl_data->ratios.horz_c);
313 filter_v_c = dpp401_dscl_get_filter_coeffs_64p(
314 scl_data->taps.v_taps_c, scl_data->ratios.vert_c);
315 }
316 }
317
318 h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3
319 && scl_data->taps.h_taps_c < 3
320 && (scl_data->taps.h_taps > 1 && scl_data->taps.h_taps_c > 1);
321 v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3
322 && scl_data->taps.v_taps_c < 3
323 && (scl_data->taps.v_taps > 1 && scl_data->taps.v_taps_c > 1);
324
325 h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0;
326 v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0;
327
328 REG_UPDATE_6(DSCL_2TAP_CONTROL,
329 SCL_H_2TAP_HARDCODE_COEF_EN, h_2tap_hardcode_coef_en,
330 SCL_H_2TAP_SHARP_EN, h_2tap_sharp_en,
331 SCL_H_2TAP_SHARP_FACTOR, h_2tap_sharp_factor,
332 SCL_V_2TAP_HARDCODE_COEF_EN, v_2tap_hardcode_coef_en,
333 SCL_V_2TAP_SHARP_EN, v_2tap_sharp_en,
334 SCL_V_2TAP_SHARP_FACTOR, v_2tap_sharp_factor);
335
336 if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) {
337 bool filter_updated = false;
338
339 filter_updated = (filter_h && (filter_h != dpp->filter_h))
340 || (filter_v && (filter_v != dpp->filter_v));
341
342 if (chroma_coef_mode) {
343 filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c))
344 || (filter_v_c && (filter_v_c != dpp->filter_v_c));
345 }
346
347 if ((filter_updated) || (force_coeffs_update)) {
348 uint32_t scl_mode = REG_READ(SCL_MODE);
349
350 if (!h_2tap_hardcode_coef_en && filter_h) {
351 dpp401_dscl_set_scaler_filter(
352 dpp, scl_data->taps.h_taps,
353 SCL_COEF_LUMA_HORZ_FILTER, filter_h);
354 }
355 dpp->filter_h = filter_h;
356 if (!v_2tap_hardcode_coef_en && filter_v) {
357 dpp401_dscl_set_scaler_filter(
358 dpp, scl_data->taps.v_taps,
359 SCL_COEF_LUMA_VERT_FILTER, filter_v);
360 }
361 dpp->filter_v = filter_v;
362 if (chroma_coef_mode) {
363 if (!h_2tap_hardcode_coef_en && filter_h_c) {
364 dpp401_dscl_set_scaler_filter(
365 dpp, scl_data->taps.h_taps_c,
366 SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
367 }
368 if (!v_2tap_hardcode_coef_en && filter_v_c) {
369 dpp401_dscl_set_scaler_filter(
370 dpp, scl_data->taps.v_taps_c,
371 SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
372 }
373 }
374 dpp->filter_h_c = filter_h_c;
375 dpp->filter_v_c = filter_v_c;
376
377 coef_ram_current = get_reg_field_value_ex(
378 scl_mode, dpp->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
379 dpp->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
380
381 /* Swap coefficient RAM and set chroma coefficient mode */
382 REG_SET_2(SCL_MODE, scl_mode,
383 SCL_COEF_RAM_SELECT, !coef_ram_current,
384 SCL_CHROMA_COEF_MODE, chroma_coef_mode);
385 }
386 }
387 }
388
389 // TODO: Fix defined but not used error
390 //static int dpp401_dscl_get_lb_depth_bpc(enum lb_pixel_depth depth)
391 //{
392 // if (depth == LB_PIXEL_DEPTH_30BPP)
393 // return 10;
394 // else if (depth == LB_PIXEL_DEPTH_24BPP)
395 // return 8;
396 // else if (depth == LB_PIXEL_DEPTH_18BPP)
397 // return 6;
398 // else if (depth == LB_PIXEL_DEPTH_36BPP)
399 // return 12;
400 // else {
401 // BREAK_TO_DEBUGGER();
402 // return -1; /* Unsupported */
403 // }
404 //}
405
406 // TODO: Fix defined but not used error
407 //void dpp401_dscl_calc_lb_num_partitions(
408 // const struct scaler_data *scl_data,
409 // enum lb_memory_config lb_config,
410 // int *num_part_y,
411 // int *num_part_c)
412 //{
413 // int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a,
414 // lb_bpc, memory_line_size_y, memory_line_size_c, memory_line_size_a;
415 //
416 // int line_size = scl_data->viewport.width < scl_data->recout.width ?
417 // scl_data->viewport.width : scl_data->recout.width;
418 // int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
419 // scl_data->viewport_c.width : scl_data->recout.width;
420 //
421 // if (line_size == 0)
422 // line_size = 1;
423 //
424 // if (line_size_c == 0)
425 // line_size_c = 1;
426 //
427 //
428 // lb_bpc = dpp401_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
429 // memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */
430 // memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */
431 // memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */
432 //
433 // if (lb_config == LB_MEMORY_CONFIG_1) {
434 // lb_memory_size = 816;
435 // lb_memory_size_c = 816;
436 // lb_memory_size_a = 984;
437 // } else if (lb_config == LB_MEMORY_CONFIG_2) {
438 // lb_memory_size = 1088;
439 // lb_memory_size_c = 1088;
440 // lb_memory_size_a = 1312;
441 // } else if (lb_config == LB_MEMORY_CONFIG_3) {
442 // /* 420 mode: using 3rd mem from Y, Cr and Cb */
443 // lb_memory_size = 816 + 1088 + 848 + 848 + 848;
444 // lb_memory_size_c = 816 + 1088;
445 // lb_memory_size_a = 984 + 1312 + 456;
446 // } else {
447 // lb_memory_size = 816 + 1088 + 848;
448 // lb_memory_size_c = 816 + 1088 + 848;
449 // lb_memory_size_a = 984 + 1312 + 456;
450 // }
451 // *num_part_y = lb_memory_size / memory_line_size_y;
452 // *num_part_c = lb_memory_size_c / memory_line_size_c;
453 // num_partitions_a = lb_memory_size_a / memory_line_size_a;
454 //
455 // if (scl_data->lb_params.alpha_en
456 // && (num_partitions_a < *num_part_y))
457 // *num_part_y = num_partitions_a;
458 //
459 // if (*num_part_y > 64)
460 // *num_part_y = 64;
461 // if (*num_part_c > 64)
462 // *num_part_c = 64;
463 //
464 //}
465
dpp401_dscl_is_lb_conf_valid(int ceil_vratio,int num_partitions,int vtaps)466 static bool dpp401_dscl_is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
467 {
468 if (ceil_vratio > 2)
469 return vtaps <= (num_partitions - ceil_vratio + 2);
470 else
471 return vtaps <= num_partitions;
472 }
473
474 /*find first match configuration which meets the min required lb size*/
dpp401_dscl_find_lb_memory_config(struct dcn401_dpp * dpp,const struct scaler_data * scl_data)475 static enum lb_memory_config dpp401_dscl_find_lb_memory_config(struct dcn401_dpp *dpp,
476 const struct scaler_data *scl_data)
477 {
478 int num_part_y, num_part_c;
479 int vtaps = scl_data->taps.v_taps;
480 int vtaps_c = scl_data->taps.v_taps_c;
481 int ceil_vratio = dc_fixpt_ceil(scl_data->ratios.vert);
482 int ceil_vratio_c = dc_fixpt_ceil(scl_data->ratios.vert_c);
483
484 if (dpp->base.ctx->dc->debug.use_max_lb) {
485 if (scl_data->format == PIXEL_FORMAT_420BPP8
486 || scl_data->format == PIXEL_FORMAT_420BPP10)
487 return LB_MEMORY_CONFIG_3;
488 return LB_MEMORY_CONFIG_0;
489 }
490
491 dpp->base.caps->dscl_calc_lb_num_partitions(
492 scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
493
494 if (dpp401_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
495 && dpp401_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
496 return LB_MEMORY_CONFIG_1;
497
498 dpp->base.caps->dscl_calc_lb_num_partitions(
499 scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c);
500
501 if (dpp401_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
502 && dpp401_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
503 return LB_MEMORY_CONFIG_2;
504
505 if (scl_data->format == PIXEL_FORMAT_420BPP8
506 || scl_data->format == PIXEL_FORMAT_420BPP10) {
507 dpp->base.caps->dscl_calc_lb_num_partitions(
508 scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c);
509
510 if (dpp401_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
511 && dpp401_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
512 return LB_MEMORY_CONFIG_3;
513 }
514
515 dpp->base.caps->dscl_calc_lb_num_partitions(
516 scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c);
517
518 /*Ensure we can support the requested number of vtaps*/
519 ASSERT(dpp401_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
520 && dpp401_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
521
522 return LB_MEMORY_CONFIG_0;
523 }
524
525
dpp401_dscl_set_manual_ratio_init(struct dcn401_dpp * dpp,const struct scaler_data * data)526 static void dpp401_dscl_set_manual_ratio_init(
527 struct dcn401_dpp *dpp, const struct scaler_data *data)
528 {
529 uint32_t init_frac = 0;
530 uint32_t init_int = 0;
531 if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
532 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0,
533 SCL_H_SCALE_RATIO, data->dscl_prog_data.ratios.h_scale_ratio);
534
535 REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0,
536 SCL_V_SCALE_RATIO, data->dscl_prog_data.ratios.v_scale_ratio);
537
538 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0,
539 SCL_H_SCALE_RATIO_C, data->dscl_prog_data.ratios.h_scale_ratio_c);
540
541 REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0,
542 SCL_V_SCALE_RATIO_C, data->dscl_prog_data.ratios.v_scale_ratio_c);
543
544 REG_SET_2(SCL_HORZ_FILTER_INIT, 0,
545 SCL_H_INIT_FRAC, data->dscl_prog_data.init.h_filter_init_frac,
546 SCL_H_INIT_INT, data->dscl_prog_data.init.h_filter_init_int);
547
548 REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0,
549 SCL_H_INIT_FRAC_C, data->dscl_prog_data.init.h_filter_init_frac_c,
550 SCL_H_INIT_INT_C, data->dscl_prog_data.init.h_filter_init_int_c);
551
552 REG_SET_2(SCL_VERT_FILTER_INIT, 0,
553 SCL_V_INIT_FRAC, data->dscl_prog_data.init.v_filter_init_frac,
554 SCL_V_INIT_INT, data->dscl_prog_data.init.v_filter_init_int);
555
556 if (REG(SCL_VERT_FILTER_INIT_BOT)) {
557 REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
558 SCL_V_INIT_FRAC_BOT, data->dscl_prog_data.init.v_filter_init_bot_frac,
559 SCL_V_INIT_INT_BOT, data->dscl_prog_data.init.v_filter_init_bot_int);
560 }
561
562 REG_SET_2(SCL_VERT_FILTER_INIT_C, 0,
563 SCL_V_INIT_FRAC_C, data->dscl_prog_data.init.v_filter_init_frac_c,
564 SCL_V_INIT_INT_C, data->dscl_prog_data.init.v_filter_init_int_c);
565
566 if (REG(SCL_VERT_FILTER_INIT_BOT_C)) {
567 REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
568 SCL_V_INIT_FRAC_BOT_C, data->dscl_prog_data.init.v_filter_init_bot_frac_c,
569 SCL_V_INIT_INT_BOT_C, data->dscl_prog_data.init.v_filter_init_bot_int_c);
570 }
571 return;
572 }
573 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0,
574 SCL_H_SCALE_RATIO, dc_fixpt_u3d19(data->ratios.horz) << 5);
575
576 REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0,
577 SCL_V_SCALE_RATIO, dc_fixpt_u3d19(data->ratios.vert) << 5);
578
579 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0,
580 SCL_H_SCALE_RATIO_C, dc_fixpt_u3d19(data->ratios.horz_c) << 5);
581
582 REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0,
583 SCL_V_SCALE_RATIO_C, dc_fixpt_u3d19(data->ratios.vert_c) << 5);
584
585 /*
586 * 0.24 format for fraction, first five bits zeroed
587 */
588 init_frac = dc_fixpt_u0d19(data->inits.h) << 5;
589 init_int = dc_fixpt_floor(data->inits.h);
590 REG_SET_2(SCL_HORZ_FILTER_INIT, 0,
591 SCL_H_INIT_FRAC, init_frac,
592 SCL_H_INIT_INT, init_int);
593
594 init_frac = dc_fixpt_u0d19(data->inits.h_c) << 5;
595 init_int = dc_fixpt_floor(data->inits.h_c);
596 REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0,
597 SCL_H_INIT_FRAC_C, init_frac,
598 SCL_H_INIT_INT_C, init_int);
599
600 init_frac = dc_fixpt_u0d19(data->inits.v) << 5;
601 init_int = dc_fixpt_floor(data->inits.v);
602 REG_SET_2(SCL_VERT_FILTER_INIT, 0,
603 SCL_V_INIT_FRAC, init_frac,
604 SCL_V_INIT_INT, init_int);
605
606 if (REG(SCL_VERT_FILTER_INIT_BOT)) {
607 struct fixed31_32 bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
608
609 init_frac = dc_fixpt_u0d19(bot) << 5;
610 init_int = dc_fixpt_floor(bot);
611 REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
612 SCL_V_INIT_FRAC_BOT, init_frac,
613 SCL_V_INIT_INT_BOT, init_int);
614 }
615
616 init_frac = dc_fixpt_u0d19(data->inits.v_c) << 5;
617 init_int = dc_fixpt_floor(data->inits.v_c);
618 REG_SET_2(SCL_VERT_FILTER_INIT_C, 0,
619 SCL_V_INIT_FRAC_C, init_frac,
620 SCL_V_INIT_INT_C, init_int);
621
622 if (REG(SCL_VERT_FILTER_INIT_BOT_C)) {
623 struct fixed31_32 bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
624
625 init_frac = dc_fixpt_u0d19(bot) << 5;
626 init_int = dc_fixpt_floor(bot);
627 REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
628 SCL_V_INIT_FRAC_BOT_C, init_frac,
629 SCL_V_INIT_INT_BOT_C, init_int);
630 }
631 }
632
633 /**
634 * dpp401_dscl_set_recout - Set the first pixel of RECOUT in the OTG active area
635 *
636 * @dpp: DPP data struct
637 * @recout: Rectangle information
638 *
639 * This function sets the MPC RECOUT_START and RECOUT_SIZE registers based on
640 * the values specified in the recount parameter.
641 *
642 * Note: This function only have effect if AutoCal is disabled.
643 */
dpp401_dscl_set_recout(struct dcn401_dpp * dpp,const struct rect * recout)644 static void dpp401_dscl_set_recout(struct dcn401_dpp *dpp,
645 const struct rect *recout)
646 {
647 REG_SET_2(RECOUT_START, 0,
648 /* First pixel of RECOUT in the active OTG area */
649 RECOUT_START_X, recout->x,
650 /* First line of RECOUT in the active OTG area */
651 RECOUT_START_Y, recout->y);
652
653 REG_SET_2(RECOUT_SIZE, 0,
654 /* Number of RECOUT horizontal pixels */
655 RECOUT_WIDTH, recout->width,
656 /* Number of RECOUT vertical lines */
657 RECOUT_HEIGHT, recout->height);
658 }
659 /**
660 * dpp401_dscl_program_easf_v - Program EASF_V
661 *
662 * @dpp_base: High level DPP struct
663 * @scl_data: scalaer_data info
664 *
665 * This is the primary function to program vertical EASF registers
666 *
667 */
dpp401_dscl_program_easf_v(struct dpp * dpp_base,const struct scaler_data * scl_data)668 static void dpp401_dscl_program_easf_v(struct dpp *dpp_base, const struct scaler_data *scl_data)
669 {
670 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
671
672 PERF_TRACE();
673 /* DSCL_EASF_V_MODE */
674 REG_SET_3(DSCL_EASF_V_MODE, 0,
675 SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en,
676 SCL_EASF_V_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_v_sharp_factor,
677 SCL_EASF_V_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_v_ring);
678
679 if (!scl_data->dscl_prog_data.easf_v_en) {
680 PERF_TRACE();
681 return;
682 }
683
684 /* DSCL_EASF_V_BF_CNTL */
685 REG_SET_6(DSCL_EASF_V_BF_CNTL, 0,
686 SCL_EASF_V_BF1_EN, scl_data->dscl_prog_data.easf_v_bf1_en,
687 SCL_EASF_V_BF2_MODE, scl_data->dscl_prog_data.easf_v_bf2_mode,
688 SCL_EASF_V_BF3_MODE, scl_data->dscl_prog_data.easf_v_bf3_mode,
689 SCL_EASF_V_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat1_gain,
690 SCL_EASF_V_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_v_bf2_flat2_gain,
691 SCL_EASF_V_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_v_bf2_roc_gain);
692 /* DSCL_EASF_V_RINGEST_3TAP_CNTLn */
693 REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL1, 0,
694 SCL_EASF_V_RINGEST_3TAP_DNTILT_UPTILT, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_uptilt,
695 SCL_EASF_V_RINGEST_3TAP_UPTILT_MAXVAL, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt_max);
696 REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL2, 0,
697 SCL_EASF_V_RINGEST_3TAP_DNTILT_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_dntilt_slope,
698 SCL_EASF_V_RINGEST_3TAP_UPTILT1_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt1_slope);
699 REG_SET_2(DSCL_EASF_V_RINGEST_3TAP_CNTL3, 0,
700 SCL_EASF_V_RINGEST_3TAP_UPTILT2_SLOPE, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_slope,
701 SCL_EASF_V_RINGEST_3TAP_UPTILT2_OFFSET, scl_data->dscl_prog_data.easf_v_ringest_3tap_uptilt2_offset);
702 /* DSCL_EASF_V_RINGEST_EVENTAP_REDUCE */
703 REG_SET_2(DSCL_EASF_V_RINGEST_EVENTAP_REDUCE, 0,
704 SCL_EASF_V_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg1,
705 SCL_EASF_V_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_v_ringest_eventap_reduceg2);
706 /* DSCL_EASF_V_RINGEST_EVENTAP_GAIN */
707 REG_SET_2(DSCL_EASF_V_RINGEST_EVENTAP_GAIN, 0,
708 SCL_EASF_V_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain1,
709 SCL_EASF_V_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_v_ringest_eventap_gain2);
710 /* DSCL_EASF_V_BF_FINAL_MAX_MIN */
711 REG_SET_4(DSCL_EASF_V_BF_FINAL_MAX_MIN, 0,
712 SCL_EASF_V_BF_MAXA, scl_data->dscl_prog_data.easf_v_bf_maxa,
713 SCL_EASF_V_BF_MAXB, scl_data->dscl_prog_data.easf_v_bf_maxb,
714 SCL_EASF_V_BF_MINA, scl_data->dscl_prog_data.easf_v_bf_mina,
715 SCL_EASF_V_BF_MINB, scl_data->dscl_prog_data.easf_v_bf_minb);
716 /* DSCL_EASF_V_BF1_PWL_SEGn */
717 REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG0, 0,
718 SCL_EASF_V_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg0,
719 SCL_EASF_V_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg0,
720 SCL_EASF_V_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg0);
721 REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG1, 0,
722 SCL_EASF_V_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg1,
723 SCL_EASF_V_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg1,
724 SCL_EASF_V_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg1);
725 REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG2, 0,
726 SCL_EASF_V_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg2,
727 SCL_EASF_V_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg2,
728 SCL_EASF_V_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg2);
729 REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG3, 0,
730 SCL_EASF_V_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg3,
731 SCL_EASF_V_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg3,
732 SCL_EASF_V_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg3);
733 REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG4, 0,
734 SCL_EASF_V_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg4,
735 SCL_EASF_V_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg4,
736 SCL_EASF_V_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg4);
737 REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG5, 0,
738 SCL_EASF_V_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg5,
739 SCL_EASF_V_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg5,
740 SCL_EASF_V_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg5);
741 REG_SET_3(DSCL_EASF_V_BF1_PWL_SEG6, 0,
742 SCL_EASF_V_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg6,
743 SCL_EASF_V_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg6,
744 SCL_EASF_V_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_v_bf1_pwl_slope_seg6);
745 REG_SET_2(DSCL_EASF_V_BF1_PWL_SEG7, 0,
746 SCL_EASF_V_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_in_seg7,
747 SCL_EASF_V_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_v_bf1_pwl_base_seg7);
748 /* DSCL_EASF_V_BF3_PWL_SEGn */
749 REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG0, 0,
750 SCL_EASF_V_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set0,
751 SCL_EASF_V_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set0,
752 SCL_EASF_V_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set0);
753 REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG1, 0,
754 SCL_EASF_V_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set1,
755 SCL_EASF_V_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set1,
756 SCL_EASF_V_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set1);
757 REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG2, 0,
758 SCL_EASF_V_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set2,
759 SCL_EASF_V_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set2,
760 SCL_EASF_V_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set2);
761 REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG3, 0,
762 SCL_EASF_V_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set3,
763 SCL_EASF_V_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set3,
764 SCL_EASF_V_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set3);
765 REG_SET_3(DSCL_EASF_V_BF3_PWL_SEG4, 0,
766 SCL_EASF_V_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set4,
767 SCL_EASF_V_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set4,
768 SCL_EASF_V_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_v_bf3_pwl_slope_set4);
769 REG_SET_2(DSCL_EASF_V_BF3_PWL_SEG5, 0,
770 SCL_EASF_V_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_in_set5,
771 SCL_EASF_V_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_v_bf3_pwl_base_set5);
772 PERF_TRACE();
773 }
774 /**
775 * dpp401_dscl_program_easf_h - Program EASF_H
776 *
777 * @dpp_base: High level DPP struct
778 * @scl_data: scalaer_data info
779 *
780 * This is the primary function to program horizontal EASF registers
781 *
782 */
dpp401_dscl_program_easf_h(struct dpp * dpp_base,const struct scaler_data * scl_data)783 static void dpp401_dscl_program_easf_h(struct dpp *dpp_base, const struct scaler_data *scl_data)
784 {
785 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
786
787 PERF_TRACE();
788 /* DSCL_EASF_H_MODE */
789 REG_SET_3(DSCL_EASF_H_MODE, 0,
790 SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en,
791 SCL_EASF_H_2TAP_SHARP_FACTOR, scl_data->dscl_prog_data.easf_h_sharp_factor,
792 SCL_EASF_H_RINGEST_FORCE_EN, scl_data->dscl_prog_data.easf_h_ring);
793
794 if (!scl_data->dscl_prog_data.easf_h_en) {
795 PERF_TRACE();
796 return;
797 }
798
799 /* DSCL_EASF_H_BF_CNTL */
800 REG_SET_6(DSCL_EASF_H_BF_CNTL, 0,
801 SCL_EASF_H_BF1_EN, scl_data->dscl_prog_data.easf_h_bf1_en,
802 SCL_EASF_H_BF2_MODE, scl_data->dscl_prog_data.easf_h_bf2_mode,
803 SCL_EASF_H_BF3_MODE, scl_data->dscl_prog_data.easf_h_bf3_mode,
804 SCL_EASF_H_BF2_FLAT1_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat1_gain,
805 SCL_EASF_H_BF2_FLAT2_GAIN, scl_data->dscl_prog_data.easf_h_bf2_flat2_gain,
806 SCL_EASF_H_BF2_ROC_GAIN, scl_data->dscl_prog_data.easf_h_bf2_roc_gain);
807 /* DSCL_EASF_H_RINGEST_EVENTAP_REDUCE */
808 REG_SET_2(DSCL_EASF_H_RINGEST_EVENTAP_REDUCE, 0,
809 SCL_EASF_H_RINGEST_EVENTAP_REDUCEG1, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg1,
810 SCL_EASF_H_RINGEST_EVENTAP_REDUCEG2, scl_data->dscl_prog_data.easf_h_ringest_eventap_reduceg2);
811 /* DSCL_EASF_H_RINGEST_EVENTAP_GAIN */
812 REG_SET_2(DSCL_EASF_H_RINGEST_EVENTAP_GAIN, 0,
813 SCL_EASF_H_RINGEST_EVENTAP_GAIN1, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain1,
814 SCL_EASF_H_RINGEST_EVENTAP_GAIN2, scl_data->dscl_prog_data.easf_h_ringest_eventap_gain2);
815 /* DSCL_EASF_H_BF_FINAL_MAX_MIN */
816 REG_SET_4(DSCL_EASF_H_BF_FINAL_MAX_MIN, 0,
817 SCL_EASF_H_BF_MAXA, scl_data->dscl_prog_data.easf_h_bf_maxa,
818 SCL_EASF_H_BF_MAXB, scl_data->dscl_prog_data.easf_h_bf_maxb,
819 SCL_EASF_H_BF_MINA, scl_data->dscl_prog_data.easf_h_bf_mina,
820 SCL_EASF_H_BF_MINB, scl_data->dscl_prog_data.easf_h_bf_minb);
821 /* DSCL_EASF_H_BF1_PWL_SEGn */
822 REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG0, 0,
823 SCL_EASF_H_BF1_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg0,
824 SCL_EASF_H_BF1_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg0,
825 SCL_EASF_H_BF1_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg0);
826 REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG1, 0,
827 SCL_EASF_H_BF1_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg1,
828 SCL_EASF_H_BF1_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg1,
829 SCL_EASF_H_BF1_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg1);
830 REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG2, 0,
831 SCL_EASF_H_BF1_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg2,
832 SCL_EASF_H_BF1_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg2,
833 SCL_EASF_H_BF1_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg2);
834 REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG3, 0,
835 SCL_EASF_H_BF1_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg3,
836 SCL_EASF_H_BF1_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg3,
837 SCL_EASF_H_BF1_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg3);
838 REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG4, 0,
839 SCL_EASF_H_BF1_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg4,
840 SCL_EASF_H_BF1_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg4,
841 SCL_EASF_H_BF1_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg4);
842 REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG5, 0,
843 SCL_EASF_H_BF1_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg5,
844 SCL_EASF_H_BF1_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg5,
845 SCL_EASF_H_BF1_PWL_SLOPE_SEG5, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg5);
846 REG_SET_3(DSCL_EASF_H_BF1_PWL_SEG6, 0,
847 SCL_EASF_H_BF1_PWL_IN_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg6,
848 SCL_EASF_H_BF1_PWL_BASE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg6,
849 SCL_EASF_H_BF1_PWL_SLOPE_SEG6, scl_data->dscl_prog_data.easf_h_bf1_pwl_slope_seg6);
850 REG_SET_2(DSCL_EASF_H_BF1_PWL_SEG7, 0,
851 SCL_EASF_H_BF1_PWL_IN_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_in_seg7,
852 SCL_EASF_H_BF1_PWL_BASE_SEG7, scl_data->dscl_prog_data.easf_h_bf1_pwl_base_seg7);
853 /* DSCL_EASF_H_BF3_PWL_SEGn */
854 REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG0, 0,
855 SCL_EASF_H_BF3_PWL_IN_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set0,
856 SCL_EASF_H_BF3_PWL_BASE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set0,
857 SCL_EASF_H_BF3_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set0);
858 REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG1, 0,
859 SCL_EASF_H_BF3_PWL_IN_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set1,
860 SCL_EASF_H_BF3_PWL_BASE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set1,
861 SCL_EASF_H_BF3_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set1);
862 REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG2, 0,
863 SCL_EASF_H_BF3_PWL_IN_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set2,
864 SCL_EASF_H_BF3_PWL_BASE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set2,
865 SCL_EASF_H_BF3_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set2);
866 REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG3, 0,
867 SCL_EASF_H_BF3_PWL_IN_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set3,
868 SCL_EASF_H_BF3_PWL_BASE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set3,
869 SCL_EASF_H_BF3_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set3);
870 REG_SET_3(DSCL_EASF_H_BF3_PWL_SEG4, 0,
871 SCL_EASF_H_BF3_PWL_IN_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set4,
872 SCL_EASF_H_BF3_PWL_BASE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set4,
873 SCL_EASF_H_BF3_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.easf_h_bf3_pwl_slope_set4);
874 REG_SET_2(DSCL_EASF_H_BF3_PWL_SEG5, 0,
875 SCL_EASF_H_BF3_PWL_IN_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_in_set5,
876 SCL_EASF_H_BF3_PWL_BASE_SEG5, scl_data->dscl_prog_data.easf_h_bf3_pwl_base_set5);
877 PERF_TRACE();
878 }
879 /**
880 * dpp401_dscl_program_easf - Program EASF
881 *
882 * @dpp_base: High level DPP struct
883 * @scl_data: scalaer_data info
884 *
885 * This is the primary function to program EASF
886 *
887 */
dpp401_dscl_program_easf(struct dpp * dpp_base,const struct scaler_data * scl_data)888 static void dpp401_dscl_program_easf(struct dpp *dpp_base, const struct scaler_data *scl_data)
889 {
890 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
891
892 PERF_TRACE();
893 /* DSCL_SC_MODE */
894 REG_SET_2(DSCL_SC_MODE, 0,
895 SCL_SC_MATRIX_MODE, scl_data->dscl_prog_data.easf_matrix_mode,
896 SCL_SC_LTONL_EN, scl_data->dscl_prog_data.easf_ltonl_en);
897 /* DSCL_EASF_SC_MATRIX_C0C1, DSCL_EASF_SC_MATRIX_C2C3 */
898 REG_SET_2(DSCL_SC_MATRIX_C0C1, 0,
899 SCL_SC_MATRIX_C0, scl_data->dscl_prog_data.easf_matrix_c0,
900 SCL_SC_MATRIX_C1, scl_data->dscl_prog_data.easf_matrix_c1);
901 REG_SET_2(DSCL_SC_MATRIX_C2C3, 0,
902 SCL_SC_MATRIX_C2, scl_data->dscl_prog_data.easf_matrix_c2,
903 SCL_SC_MATRIX_C3, scl_data->dscl_prog_data.easf_matrix_c3);
904 dpp401_dscl_program_easf_v(dpp_base, scl_data);
905 dpp401_dscl_program_easf_h(dpp_base, scl_data);
906 PERF_TRACE();
907 }
908 /**
909 * dpp401_dscl_disable_easf - Disable EASF when no scaling (1:1)
910 *
911 * @dpp_base: High level DPP struct
912 * @scl_data: scalaer_data info
913 *
914 * When we have 1:1 scaling, we need to disable EASF
915 *
916 */
dpp401_dscl_disable_easf(struct dpp * dpp_base,const struct scaler_data * scl_data)917 static void dpp401_dscl_disable_easf(struct dpp *dpp_base, const struct scaler_data *scl_data)
918 {
919 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
920
921 PERF_TRACE();
922 /* DSCL_EASF_V_MODE */
923 REG_UPDATE(DSCL_EASF_V_MODE,
924 SCL_EASF_V_EN, scl_data->dscl_prog_data.easf_v_en);
925 /* DSCL_EASF_H_MODE */
926 REG_UPDATE(DSCL_EASF_H_MODE,
927 SCL_EASF_H_EN, scl_data->dscl_prog_data.easf_h_en);
928 PERF_TRACE();
929 }
dpp401_dscl_set_isharp_filter(struct dcn401_dpp * dpp,const uint32_t * filter)930 static void dpp401_dscl_set_isharp_filter(
931 struct dcn401_dpp *dpp, const uint32_t *filter)
932 {
933 int level;
934 uint32_t filter_data;
935 if (filter == NULL)
936 return;
937
938 REG_UPDATE(ISHARP_DELTA_CTRL,
939 ISHARP_DELTA_LUT_HOST_SELECT, 0);
940 /* LUT data write is auto-indexed. Write index once */
941 REG_SET(ISHARP_DELTA_INDEX, 0,
942 ISHARP_DELTA_INDEX, 0);
943 for (level = 0; level < NUM_LEVELS; level++) {
944 filter_data = filter[level];
945 REG_SET(ISHARP_DELTA_DATA, 0,
946 ISHARP_DELTA_DATA, filter_data);
947 }
948 } // dpp401_dscl_set_isharp_filter
949 /**
950 * dpp401_dscl_program_isharp - Program isharp
951 *
952 * @dpp_base: High level DPP struct
953 * @scl_data: scalaer_data info
954 * @program_isharp_1dlut: flag to program isharp 1D LUT
955 * @bs_coeffs_updated: Blur and Scale Coefficients update flag
956 *
957 * This is the primary function to program isharp
958 *
959 */
dpp401_dscl_program_isharp(struct dpp * dpp_base,const struct scaler_data * scl_data,bool program_isharp_1dlut,bool * bs_coeffs_updated)960 static void dpp401_dscl_program_isharp(struct dpp *dpp_base,
961 const struct scaler_data *scl_data,
962 bool program_isharp_1dlut,
963 bool *bs_coeffs_updated)
964 {
965 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
966 *bs_coeffs_updated = false;
967
968 PERF_TRACE();
969 /* ISHARP_MODE */
970 REG_SET_6(ISHARP_MODE, 0,
971 ISHARP_EN, scl_data->dscl_prog_data.isharp_en,
972 ISHARP_NOISEDET_EN, scl_data->dscl_prog_data.isharp_noise_det.enable,
973 ISHARP_NOISEDET_MODE, scl_data->dscl_prog_data.isharp_noise_det.mode,
974 ISHARP_LBA_MODE, scl_data->dscl_prog_data.isharp_lba.mode,
975 ISHARP_FMT_MODE, scl_data->dscl_prog_data.isharp_fmt.mode,
976 ISHARP_FMT_NORM, scl_data->dscl_prog_data.isharp_fmt.norm);
977
978 /* Skip remaining register programming if ISHARP is disabled */
979 if (!scl_data->dscl_prog_data.isharp_en) {
980 PERF_TRACE();
981 return;
982 }
983
984 /* ISHARP_NOISEDET_THRESHOLD */
985 REG_SET_2(ISHARP_NOISEDET_THRESHOLD, 0,
986 ISHARP_NOISEDET_UTHRE, scl_data->dscl_prog_data.isharp_noise_det.uthreshold,
987 ISHARP_NOISEDET_DTHRE, scl_data->dscl_prog_data.isharp_noise_det.dthreshold);
988
989 /* ISHARP_NOISE_GAIN_PWL */
990 REG_SET_3(ISHARP_NOISE_GAIN_PWL, 0,
991 ISHARP_NOISEDET_PWL_START_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_start_in,
992 ISHARP_NOISEDET_PWL_END_IN, scl_data->dscl_prog_data.isharp_noise_det.pwl_end_in,
993 ISHARP_NOISEDET_PWL_SLOPE, scl_data->dscl_prog_data.isharp_noise_det.pwl_slope);
994
995 /* ISHARP_LBA: IN_SEG, BASE_SEG, SLOPE_SEG */
996 REG_SET_3(ISHARP_LBA_PWL_SEG0, 0,
997 ISHARP_LBA_PWL_IN_SEG0, scl_data->dscl_prog_data.isharp_lba.in_seg[0],
998 ISHARP_LBA_PWL_BASE_SEG0, scl_data->dscl_prog_data.isharp_lba.base_seg[0],
999 ISHARP_LBA_PWL_SLOPE_SEG0, scl_data->dscl_prog_data.isharp_lba.slope_seg[0]);
1000 REG_SET_3(ISHARP_LBA_PWL_SEG1, 0,
1001 ISHARP_LBA_PWL_IN_SEG1, scl_data->dscl_prog_data.isharp_lba.in_seg[1],
1002 ISHARP_LBA_PWL_BASE_SEG1, scl_data->dscl_prog_data.isharp_lba.base_seg[1],
1003 ISHARP_LBA_PWL_SLOPE_SEG1, scl_data->dscl_prog_data.isharp_lba.slope_seg[1]);
1004 REG_SET_3(ISHARP_LBA_PWL_SEG2, 0,
1005 ISHARP_LBA_PWL_IN_SEG2, scl_data->dscl_prog_data.isharp_lba.in_seg[2],
1006 ISHARP_LBA_PWL_BASE_SEG2, scl_data->dscl_prog_data.isharp_lba.base_seg[2],
1007 ISHARP_LBA_PWL_SLOPE_SEG2, scl_data->dscl_prog_data.isharp_lba.slope_seg[2]);
1008 REG_SET_3(ISHARP_LBA_PWL_SEG3, 0,
1009 ISHARP_LBA_PWL_IN_SEG3, scl_data->dscl_prog_data.isharp_lba.in_seg[3],
1010 ISHARP_LBA_PWL_BASE_SEG3, scl_data->dscl_prog_data.isharp_lba.base_seg[3],
1011 ISHARP_LBA_PWL_SLOPE_SEG3, scl_data->dscl_prog_data.isharp_lba.slope_seg[3]);
1012 REG_SET_3(ISHARP_LBA_PWL_SEG4, 0,
1013 ISHARP_LBA_PWL_IN_SEG4, scl_data->dscl_prog_data.isharp_lba.in_seg[4],
1014 ISHARP_LBA_PWL_BASE_SEG4, scl_data->dscl_prog_data.isharp_lba.base_seg[4],
1015 ISHARP_LBA_PWL_SLOPE_SEG4, scl_data->dscl_prog_data.isharp_lba.slope_seg[4]);
1016 REG_SET_2(ISHARP_LBA_PWL_SEG5, 0,
1017 ISHARP_LBA_PWL_IN_SEG5, scl_data->dscl_prog_data.isharp_lba.in_seg[5],
1018 ISHARP_LBA_PWL_BASE_SEG5, scl_data->dscl_prog_data.isharp_lba.base_seg[5]);
1019
1020 /* ISHARP_DELTA_LUT */
1021 if (!program_isharp_1dlut)
1022 dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
1023
1024 /* ISHARP_NLDELTA_SOFT_CLIP */
1025 REG_SET_6(ISHARP_NLDELTA_SOFT_CLIP, 0,
1026 ISHARP_NLDELTA_SCLIP_EN_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_p,
1027 ISHARP_NLDELTA_SCLIP_PIVOT_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_p,
1028 ISHARP_NLDELTA_SCLIP_SLOPE_P, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_p,
1029 ISHARP_NLDELTA_SCLIP_EN_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.enable_n,
1030 ISHARP_NLDELTA_SCLIP_PIVOT_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.pivot_n,
1031 ISHARP_NLDELTA_SCLIP_SLOPE_N, scl_data->dscl_prog_data.isharp_nldelta_sclip.slope_n);
1032
1033 /* Blur and Scale Coefficients - SCL_COEF_RAM_TAP_SELECT */
1034 if (scl_data->dscl_prog_data.isharp_en) {
1035 if (scl_data->dscl_prog_data.filter_blur_scale_v) {
1036 dpp401_dscl_set_scaler_filter(
1037 dpp, scl_data->taps.v_taps,
1038 SCL_COEF_VERTICAL_BLUR_SCALE,
1039 scl_data->dscl_prog_data.filter_blur_scale_v);
1040 *bs_coeffs_updated = true;
1041 }
1042 if (scl_data->dscl_prog_data.filter_blur_scale_h) {
1043 dpp401_dscl_set_scaler_filter(
1044 dpp, scl_data->taps.h_taps,
1045 SCL_COEF_HORIZONTAL_BLUR_SCALE,
1046 scl_data->dscl_prog_data.filter_blur_scale_h);
1047 *bs_coeffs_updated = true;
1048 }
1049 }
1050 PERF_TRACE();
1051 } // dpp401_dscl_program_isharp
1052 /**
1053 * dpp401_dscl_set_scaler_manual_scale - Manually program scaler and line buffer
1054 *
1055 * @dpp_base: High level DPP struct
1056 * @scl_data: scalaer_data info
1057 *
1058 * This is the primary function to program scaler and line buffer in manual
1059 * scaling mode. To execute the required operations for manual scale, we need
1060 * to disable AutoCal first.
1061 */
dpp401_dscl_set_scaler_manual_scale(struct dpp * dpp_base,const struct scaler_data * scl_data)1062 void dpp401_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
1063 const struct scaler_data *scl_data)
1064 {
1065 enum lb_memory_config lb_config;
1066 struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
1067 const struct rect *rect = &scl_data->recout;
1068 uint32_t mpc_width = scl_data->h_active;
1069 uint32_t mpc_height = scl_data->v_active;
1070 uint32_t v_num_taps = scl_data->taps.v_taps - 1;
1071 uint32_t v_num_taps_c = scl_data->taps.v_taps_c - 1;
1072 uint32_t h_num_taps = scl_data->taps.h_taps - 1;
1073 uint32_t h_num_taps_c = scl_data->taps.h_taps_c - 1;
1074 enum dscl_mode_sel dscl_mode = dpp401_dscl_get_dscl_mode(
1075 dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
1076 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
1077 && scl_data->format <= PIXEL_FORMAT_VIDEO_END;
1078 bool program_isharp_1dlut = false;
1079 bool bs_coeffs_updated = false;
1080
1081
1082 if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
1083 return;
1084
1085 PERF_TRACE();
1086
1087 /* If only sharpness has changed, then only update 1dlut, then return */
1088 if (scl_data->dscl_prog_data.isharp_en &&
1089 (dpp->scl_data.dscl_prog_data.sharpness_level
1090 != scl_data->dscl_prog_data.sharpness_level)) {
1091 /* ISHARP_DELTA_LUT */
1092 dpp401_dscl_set_isharp_filter(dpp, scl_data->dscl_prog_data.isharp_delta);
1093 dpp->scl_data.dscl_prog_data.sharpness_level = scl_data->dscl_prog_data.sharpness_level;
1094 dpp->scl_data.dscl_prog_data.isharp_delta = scl_data->dscl_prog_data.isharp_delta;
1095
1096 if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
1097 return;
1098 program_isharp_1dlut = true;
1099 }
1100
1101 dpp->scl_data = *scl_data;
1102
1103 if ((dpp->base.ctx->dc->config.use_spl) && (!dpp->base.ctx->dc->debug.disable_spl)) {
1104 dscl_mode = (enum dscl_mode_sel) scl_data->dscl_prog_data.dscl_mode;
1105 rect = (struct rect *)&scl_data->dscl_prog_data.recout;
1106 mpc_width = scl_data->dscl_prog_data.mpc_size.width;
1107 mpc_height = scl_data->dscl_prog_data.mpc_size.height;
1108 v_num_taps = scl_data->dscl_prog_data.taps.v_taps;
1109 v_num_taps_c = scl_data->dscl_prog_data.taps.v_taps_c;
1110 h_num_taps = scl_data->dscl_prog_data.taps.h_taps;
1111 h_num_taps_c = scl_data->dscl_prog_data.taps.h_taps_c;
1112 }
1113 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl) {
1114 if (dscl_mode != DSCL_MODE_DSCL_BYPASS)
1115 dpp401_power_on_dscl(dpp_base, true);
1116 }
1117
1118 /* Autocal off */
1119 REG_SET_3(DSCL_AUTOCAL, 0,
1120 AUTOCAL_MODE, AUTOCAL_MODE_OFF,
1121 AUTOCAL_NUM_PIPE, 0,
1122 AUTOCAL_PIPE_ID, 0);
1123
1124 /*clean scaler boundary mode when Autocal off*/
1125 REG_SET(DSCL_CONTROL, 0,
1126 SCL_BOUNDARY_MODE, 0);
1127
1128 /* Recout */
1129 dpp401_dscl_set_recout(dpp, rect);
1130
1131 /* MPC Size */
1132 REG_SET_2(MPC_SIZE, 0,
1133 /* Number of horizontal pixels of MPC */
1134 MPC_WIDTH, mpc_width,
1135 /* Number of vertical lines of MPC */
1136 MPC_HEIGHT, mpc_height);
1137
1138 /* SCL mode */
1139 REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode);
1140
1141 if (dscl_mode == DSCL_MODE_DSCL_BYPASS) {
1142 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl)
1143 dpp401_power_on_dscl(dpp_base, false);
1144 return;
1145 }
1146
1147 /* LB */
1148 lb_config = dpp401_dscl_find_lb_memory_config(dpp, scl_data);
1149 dpp401_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
1150
1151 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) {
1152 if (dpp->base.ctx->dc->config.prefer_easf)
1153 dpp401_dscl_disable_easf(dpp_base, scl_data);
1154 dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
1155 return;
1156 }
1157
1158 /* Black offsets */
1159 if (REG(SCL_BLACK_OFFSET)) {
1160 if (ycbcr)
1161 REG_SET_2(SCL_BLACK_OFFSET, 0,
1162 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y,
1163 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR);
1164 else
1165
1166 REG_SET_2(SCL_BLACK_OFFSET, 0,
1167 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y,
1168 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y);
1169 }
1170
1171 /* Manually calculate scale ratio and init values */
1172 dpp401_dscl_set_manual_ratio_init(dpp, scl_data);
1173
1174 /* HTaps/VTaps */
1175 REG_SET_4(SCL_TAP_CONTROL, 0,
1176 SCL_V_NUM_TAPS, v_num_taps,
1177 SCL_H_NUM_TAPS, h_num_taps,
1178 SCL_V_NUM_TAPS_C, v_num_taps_c,
1179 SCL_H_NUM_TAPS_C, h_num_taps_c);
1180
1181 /* ISharp configuration
1182 * - B&S coeffs are written to same coeff RAM as WB scaler coeffs
1183 * - coeff RAM toggle is in EASF programming
1184 * - if we are only programming B&S coeffs, then need to reprogram
1185 * WB scaler coeffs and toggle coeff RAM together
1186 */
1187 //if (dpp->base.ctx->dc->config.prefer_easf)
1188 dpp401_dscl_program_isharp(dpp_base, scl_data, program_isharp_1dlut, &bs_coeffs_updated);
1189
1190 dpp401_dscl_set_scl_filter(dpp, scl_data, ycbcr, bs_coeffs_updated);
1191 /* Edge adaptive scaler function configuration */
1192 if (dpp->base.ctx->dc->config.prefer_easf)
1193 dpp401_dscl_program_easf(dpp_base, scl_data);
1194 PERF_TRACE();
1195 }
1196