0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "dm_services.h"
0027
0028 #include "core_types.h"
0029
0030 #include "reg_helper.h"
0031 #include "dcn10_dpp.h"
0032 #include "basics/conversion.h"
0033
0034
0035 #define NUM_PHASES 64
0036 #define HORZ_MAX_TAPS 8
0037 #define VERT_MAX_TAPS 8
0038
0039 #define BLACK_OFFSET_RGB_Y 0x0
0040 #define BLACK_OFFSET_CBCR 0x8000
0041
0042 #define VISUAL_CONFIRM_RECT_HEIGHT_DEFAULT 3
0043 #define VISUAL_CONFIRM_RECT_HEIGHT_MIN 1
0044 #define VISUAL_CONFIRM_RECT_HEIGHT_MAX 10
0045
0046 #define REG(reg)\
0047 dpp->tf_regs->reg
0048
0049 #define CTX \
0050 dpp->base.ctx
0051
0052 #undef FN
0053 #define FN(reg_name, field_name) \
0054 dpp->tf_shift->field_name, dpp->tf_mask->field_name
0055
0056 enum dcn10_coef_filter_type_sel {
0057 SCL_COEF_LUMA_VERT_FILTER = 0,
0058 SCL_COEF_LUMA_HORZ_FILTER = 1,
0059 SCL_COEF_CHROMA_VERT_FILTER = 2,
0060 SCL_COEF_CHROMA_HORZ_FILTER = 3,
0061 SCL_COEF_ALPHA_VERT_FILTER = 4,
0062 SCL_COEF_ALPHA_HORZ_FILTER = 5
0063 };
0064
0065 enum dscl_autocal_mode {
0066 AUTOCAL_MODE_OFF = 0,
0067
0068
0069
0070
0071 AUTOCAL_MODE_AUTOSCALE = 1,
0072
0073
0074
0075 AUTOCAL_MODE_AUTOCENTER = 2,
0076
0077
0078
0079 AUTOCAL_MODE_AUTOREPLICATE = 3
0080 };
0081
0082 enum dscl_mode_sel {
0083 DSCL_MODE_SCALING_444_BYPASS = 0,
0084 DSCL_MODE_SCALING_444_RGB_ENABLE = 1,
0085 DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2,
0086 DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3,
0087 DSCL_MODE_SCALING_420_LUMA_BYPASS = 4,
0088 DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5,
0089 DSCL_MODE_DSCL_BYPASS = 6
0090 };
0091
0092 static int dpp1_dscl_get_pixel_depth_val(enum lb_pixel_depth depth)
0093 {
0094 if (depth == LB_PIXEL_DEPTH_30BPP)
0095 return 0;
0096 else if (depth == LB_PIXEL_DEPTH_24BPP)
0097 return 1;
0098 else if (depth == LB_PIXEL_DEPTH_18BPP)
0099 return 2;
0100 else if (depth == LB_PIXEL_DEPTH_36BPP)
0101 return 3;
0102 else {
0103 ASSERT(0);
0104 return -1;
0105 }
0106 }
0107
0108 static bool dpp1_dscl_is_video_format(enum pixel_format format)
0109 {
0110 if (format >= PIXEL_FORMAT_VIDEO_BEGIN
0111 && format <= PIXEL_FORMAT_VIDEO_END)
0112 return true;
0113 else
0114 return false;
0115 }
0116
0117 static bool dpp1_dscl_is_420_format(enum pixel_format format)
0118 {
0119 if (format == PIXEL_FORMAT_420BPP8 ||
0120 format == PIXEL_FORMAT_420BPP10)
0121 return true;
0122 else
0123 return false;
0124 }
0125
0126 static enum dscl_mode_sel dpp1_dscl_get_dscl_mode(
0127 struct dpp *dpp_base,
0128 const struct scaler_data *data,
0129 bool dbg_always_scale)
0130 {
0131 const long long one = dc_fixpt_one.value;
0132
0133 if (dpp_base->caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
0134
0135 if (data->format == PIXEL_FORMAT_FP16)
0136 return DSCL_MODE_DSCL_BYPASS;
0137 }
0138
0139 if (data->ratios.horz.value == one
0140 && data->ratios.vert.value == one
0141 && data->ratios.horz_c.value == one
0142 && data->ratios.vert_c.value == one
0143 && !dbg_always_scale)
0144 return DSCL_MODE_SCALING_444_BYPASS;
0145
0146 if (!dpp1_dscl_is_420_format(data->format)) {
0147 if (dpp1_dscl_is_video_format(data->format))
0148 return DSCL_MODE_SCALING_444_YCBCR_ENABLE;
0149 else
0150 return DSCL_MODE_SCALING_444_RGB_ENABLE;
0151 }
0152 if (data->ratios.horz.value == one && data->ratios.vert.value == one)
0153 return DSCL_MODE_SCALING_420_LUMA_BYPASS;
0154 if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one)
0155 return DSCL_MODE_SCALING_420_CHROMA_BYPASS;
0156
0157 return DSCL_MODE_SCALING_420_YCBCR_ENABLE;
0158 }
0159
0160 static void dpp1_power_on_dscl(
0161 struct dpp *dpp_base,
0162 bool power_on)
0163 {
0164 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
0165
0166 if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) {
0167 if (power_on) {
0168 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 0);
0169 REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5);
0170 } else {
0171 if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.dscl) {
0172 dpp->base.ctx->dc->optimized_required = true;
0173 dpp->base.deferred_reg_writes.bits.disable_dscl = true;
0174 } else {
0175 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
0176 }
0177 }
0178 }
0179 }
0180
0181
0182 static void dpp1_dscl_set_lb(
0183 struct dcn10_dpp *dpp,
0184 const struct line_buffer_params *lb_params,
0185 enum lb_memory_config mem_size_config)
0186 {
0187 uint32_t max_partitions = 63;
0188
0189
0190 if (dpp->base.caps->dscl_data_proc_format == DSCL_DATA_PRCESSING_FIXED_FORMAT) {
0191
0192 uint32_t pixel_depth = dpp1_dscl_get_pixel_depth_val(lb_params->depth);
0193 uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth;
0194
0195 REG_SET_7(LB_DATA_FORMAT, 0,
0196 PIXEL_DEPTH, pixel_depth,
0197 PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode,
0198 PIXEL_REDUCE_MODE, 1,
0199 DYNAMIC_PIXEL_DEPTH, dyn_pix_depth,
0200 DITHER_EN, 0,
0201 INTERLEAVE_EN, lb_params->interleave_en,
0202 LB_DATA_FORMAT__ALPHA_EN, lb_params->alpha_en);
0203 }
0204 else {
0205
0206 REG_SET_2(LB_DATA_FORMAT, 0,
0207 INTERLEAVE_EN, lb_params->interleave_en,
0208 LB_DATA_FORMAT__ALPHA_EN, lb_params->alpha_en);
0209 }
0210
0211 if (dpp->base.caps->max_lb_partitions == 31)
0212 max_partitions = 31;
0213
0214 REG_SET_2(LB_MEMORY_CTRL, 0,
0215 MEMORY_CONFIG, mem_size_config,
0216 LB_MAX_PARTITIONS, max_partitions);
0217 }
0218
0219 static const uint16_t *dpp1_dscl_get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
0220 {
0221 if (taps == 8)
0222 return get_filter_8tap_64p(ratio);
0223 else if (taps == 7)
0224 return get_filter_7tap_64p(ratio);
0225 else if (taps == 6)
0226 return get_filter_6tap_64p(ratio);
0227 else if (taps == 5)
0228 return get_filter_5tap_64p(ratio);
0229 else if (taps == 4)
0230 return get_filter_4tap_64p(ratio);
0231 else if (taps == 3)
0232 return get_filter_3tap_64p(ratio);
0233 else if (taps == 2)
0234 return get_filter_2tap_64p();
0235 else if (taps == 1)
0236 return NULL;
0237 else {
0238
0239 BREAK_TO_DEBUGGER();
0240 return NULL;
0241 }
0242 }
0243
0244 static void dpp1_dscl_set_scaler_filter(
0245 struct dcn10_dpp *dpp,
0246 uint32_t taps,
0247 enum dcn10_coef_filter_type_sel filter_type,
0248 const uint16_t *filter)
0249 {
0250 const int tap_pairs = (taps + 1) / 2;
0251 int phase;
0252 int pair;
0253 uint16_t odd_coef, even_coef;
0254
0255 REG_SET_3(SCL_COEF_RAM_TAP_SELECT, 0,
0256 SCL_COEF_RAM_TAP_PAIR_IDX, 0,
0257 SCL_COEF_RAM_PHASE, 0,
0258 SCL_COEF_RAM_FILTER_TYPE, filter_type);
0259
0260 for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) {
0261 for (pair = 0; pair < tap_pairs; pair++) {
0262 even_coef = filter[phase * taps + 2 * pair];
0263 if ((pair * 2 + 1) < taps)
0264 odd_coef = filter[phase * taps + 2 * pair + 1];
0265 else
0266 odd_coef = 0;
0267
0268 REG_SET_4(SCL_COEF_RAM_TAP_DATA, 0,
0269
0270 SCL_COEF_RAM_EVEN_TAP_COEF, even_coef,
0271
0272 SCL_COEF_RAM_EVEN_TAP_COEF_EN, 1,
0273
0274 SCL_COEF_RAM_ODD_TAP_COEF, odd_coef,
0275
0276 SCL_COEF_RAM_ODD_TAP_COEF_EN, 1);
0277 }
0278 }
0279
0280 }
0281
0282 static void dpp1_dscl_set_scl_filter(
0283 struct dcn10_dpp *dpp,
0284 const struct scaler_data *scl_data,
0285 bool chroma_coef_mode)
0286 {
0287 bool h_2tap_hardcode_coef_en = false;
0288 bool v_2tap_hardcode_coef_en = false;
0289 bool h_2tap_sharp_en = false;
0290 bool v_2tap_sharp_en = false;
0291 uint32_t h_2tap_sharp_factor = scl_data->sharpness.horz;
0292 uint32_t v_2tap_sharp_factor = scl_data->sharpness.vert;
0293 bool coef_ram_current;
0294 const uint16_t *filter_h = NULL;
0295 const uint16_t *filter_v = NULL;
0296 const uint16_t *filter_h_c = NULL;
0297 const uint16_t *filter_v_c = NULL;
0298
0299 h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3
0300 && scl_data->taps.h_taps_c < 3
0301 && (scl_data->taps.h_taps > 1 && scl_data->taps.h_taps_c > 1);
0302 v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3
0303 && scl_data->taps.v_taps_c < 3
0304 && (scl_data->taps.v_taps > 1 && scl_data->taps.v_taps_c > 1);
0305
0306 h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0;
0307 v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0;
0308
0309 REG_UPDATE_6(DSCL_2TAP_CONTROL,
0310 SCL_H_2TAP_HARDCODE_COEF_EN, h_2tap_hardcode_coef_en,
0311 SCL_H_2TAP_SHARP_EN, h_2tap_sharp_en,
0312 SCL_H_2TAP_SHARP_FACTOR, h_2tap_sharp_factor,
0313 SCL_V_2TAP_HARDCODE_COEF_EN, v_2tap_hardcode_coef_en,
0314 SCL_V_2TAP_SHARP_EN, v_2tap_sharp_en,
0315 SCL_V_2TAP_SHARP_FACTOR, v_2tap_sharp_factor);
0316
0317 if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) {
0318 bool filter_updated = false;
0319
0320 filter_h = dpp1_dscl_get_filter_coeffs_64p(
0321 scl_data->taps.h_taps, scl_data->ratios.horz);
0322 filter_v = dpp1_dscl_get_filter_coeffs_64p(
0323 scl_data->taps.v_taps, scl_data->ratios.vert);
0324
0325 filter_updated = (filter_h && (filter_h != dpp->filter_h))
0326 || (filter_v && (filter_v != dpp->filter_v));
0327
0328 if (chroma_coef_mode) {
0329 filter_h_c = dpp1_dscl_get_filter_coeffs_64p(
0330 scl_data->taps.h_taps_c, scl_data->ratios.horz_c);
0331 filter_v_c = dpp1_dscl_get_filter_coeffs_64p(
0332 scl_data->taps.v_taps_c, scl_data->ratios.vert_c);
0333 filter_updated = filter_updated || (filter_h_c && (filter_h_c != dpp->filter_h_c))
0334 || (filter_v_c && (filter_v_c != dpp->filter_v_c));
0335 }
0336
0337 if (filter_updated) {
0338 uint32_t scl_mode = REG_READ(SCL_MODE);
0339
0340 if (!h_2tap_hardcode_coef_en && filter_h) {
0341 dpp1_dscl_set_scaler_filter(
0342 dpp, scl_data->taps.h_taps,
0343 SCL_COEF_LUMA_HORZ_FILTER, filter_h);
0344 }
0345 dpp->filter_h = filter_h;
0346 if (!v_2tap_hardcode_coef_en && filter_v) {
0347 dpp1_dscl_set_scaler_filter(
0348 dpp, scl_data->taps.v_taps,
0349 SCL_COEF_LUMA_VERT_FILTER, filter_v);
0350 }
0351 dpp->filter_v = filter_v;
0352 if (chroma_coef_mode) {
0353 if (!h_2tap_hardcode_coef_en && filter_h_c) {
0354 dpp1_dscl_set_scaler_filter(
0355 dpp, scl_data->taps.h_taps_c,
0356 SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c);
0357 }
0358 if (!v_2tap_hardcode_coef_en && filter_v_c) {
0359 dpp1_dscl_set_scaler_filter(
0360 dpp, scl_data->taps.v_taps_c,
0361 SCL_COEF_CHROMA_VERT_FILTER, filter_v_c);
0362 }
0363 }
0364 dpp->filter_h_c = filter_h_c;
0365 dpp->filter_v_c = filter_v_c;
0366
0367 coef_ram_current = get_reg_field_value_ex(
0368 scl_mode, dpp->tf_mask->SCL_COEF_RAM_SELECT_CURRENT,
0369 dpp->tf_shift->SCL_COEF_RAM_SELECT_CURRENT);
0370
0371
0372 REG_SET_2(SCL_MODE, scl_mode,
0373 SCL_COEF_RAM_SELECT, !coef_ram_current,
0374 SCL_CHROMA_COEF_MODE, chroma_coef_mode);
0375 }
0376 }
0377 }
0378
0379 static int dpp1_dscl_get_lb_depth_bpc(enum lb_pixel_depth depth)
0380 {
0381 if (depth == LB_PIXEL_DEPTH_30BPP)
0382 return 10;
0383 else if (depth == LB_PIXEL_DEPTH_24BPP)
0384 return 8;
0385 else if (depth == LB_PIXEL_DEPTH_18BPP)
0386 return 6;
0387 else if (depth == LB_PIXEL_DEPTH_36BPP)
0388 return 12;
0389 else {
0390 BREAK_TO_DEBUGGER();
0391 return -1;
0392 }
0393 }
0394
0395 void dpp1_dscl_calc_lb_num_partitions(
0396 const struct scaler_data *scl_data,
0397 enum lb_memory_config lb_config,
0398 int *num_part_y,
0399 int *num_part_c)
0400 {
0401 int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a,
0402 lb_bpc, memory_line_size_y, memory_line_size_c, memory_line_size_a;
0403
0404 int line_size = scl_data->viewport.width < scl_data->recout.width ?
0405 scl_data->viewport.width : scl_data->recout.width;
0406 int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ?
0407 scl_data->viewport_c.width : scl_data->recout.width;
0408
0409 if (line_size == 0)
0410 line_size = 1;
0411
0412 if (line_size_c == 0)
0413 line_size_c = 1;
0414
0415
0416 lb_bpc = dpp1_dscl_get_lb_depth_bpc(scl_data->lb_params.depth);
0417 memory_line_size_y = (line_size * lb_bpc + 71) / 72;
0418 memory_line_size_c = (line_size_c * lb_bpc + 71) / 72;
0419 memory_line_size_a = (line_size + 5) / 6;
0420
0421 if (lb_config == LB_MEMORY_CONFIG_1) {
0422 lb_memory_size = 816;
0423 lb_memory_size_c = 816;
0424 lb_memory_size_a = 984;
0425 } else if (lb_config == LB_MEMORY_CONFIG_2) {
0426 lb_memory_size = 1088;
0427 lb_memory_size_c = 1088;
0428 lb_memory_size_a = 1312;
0429 } else if (lb_config == LB_MEMORY_CONFIG_3) {
0430
0431 lb_memory_size = 816 + 1088 + 848 + 848 + 848;
0432 lb_memory_size_c = 816 + 1088;
0433 lb_memory_size_a = 984 + 1312 + 456;
0434 } else {
0435 lb_memory_size = 816 + 1088 + 848;
0436 lb_memory_size_c = 816 + 1088 + 848;
0437 lb_memory_size_a = 984 + 1312 + 456;
0438 }
0439 *num_part_y = lb_memory_size / memory_line_size_y;
0440 *num_part_c = lb_memory_size_c / memory_line_size_c;
0441 num_partitions_a = lb_memory_size_a / memory_line_size_a;
0442
0443 if (scl_data->lb_params.alpha_en
0444 && (num_partitions_a < *num_part_y))
0445 *num_part_y = num_partitions_a;
0446
0447 if (*num_part_y > 64)
0448 *num_part_y = 64;
0449 if (*num_part_c > 64)
0450 *num_part_c = 64;
0451
0452 }
0453
0454 bool dpp1_dscl_is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps)
0455 {
0456 if (ceil_vratio > 2)
0457 return vtaps <= (num_partitions - ceil_vratio + 2);
0458 else
0459 return vtaps <= num_partitions;
0460 }
0461
0462
0463 static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *dpp,
0464 const struct scaler_data *scl_data)
0465 {
0466 int num_part_y, num_part_c;
0467 int vtaps = scl_data->taps.v_taps;
0468 int vtaps_c = scl_data->taps.v_taps_c;
0469 int ceil_vratio = dc_fixpt_ceil(scl_data->ratios.vert);
0470 int ceil_vratio_c = dc_fixpt_ceil(scl_data->ratios.vert_c);
0471
0472 if (dpp->base.ctx->dc->debug.use_max_lb) {
0473 if (scl_data->format == PIXEL_FORMAT_420BPP8
0474 || scl_data->format == PIXEL_FORMAT_420BPP10)
0475 return LB_MEMORY_CONFIG_3;
0476 return LB_MEMORY_CONFIG_0;
0477 }
0478
0479 dpp->base.caps->dscl_calc_lb_num_partitions(
0480 scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c);
0481
0482 if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
0483 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
0484 return LB_MEMORY_CONFIG_1;
0485
0486 dpp->base.caps->dscl_calc_lb_num_partitions(
0487 scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c);
0488
0489 if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
0490 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
0491 return LB_MEMORY_CONFIG_2;
0492
0493 if (scl_data->format == PIXEL_FORMAT_420BPP8
0494 || scl_data->format == PIXEL_FORMAT_420BPP10) {
0495 dpp->base.caps->dscl_calc_lb_num_partitions(
0496 scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c);
0497
0498 if (dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
0499 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c))
0500 return LB_MEMORY_CONFIG_3;
0501 }
0502
0503 dpp->base.caps->dscl_calc_lb_num_partitions(
0504 scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c);
0505
0506
0507 ASSERT(dpp1_dscl_is_lb_conf_valid(ceil_vratio, num_part_y, vtaps)
0508 && dpp1_dscl_is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c));
0509
0510 return LB_MEMORY_CONFIG_0;
0511 }
0512
0513
0514 static void dpp1_dscl_set_manual_ratio_init(
0515 struct dcn10_dpp *dpp, const struct scaler_data *data)
0516 {
0517 uint32_t init_frac = 0;
0518 uint32_t init_int = 0;
0519
0520 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0,
0521 SCL_H_SCALE_RATIO, dc_fixpt_u3d19(data->ratios.horz) << 5);
0522
0523 REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0,
0524 SCL_V_SCALE_RATIO, dc_fixpt_u3d19(data->ratios.vert) << 5);
0525
0526 REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0,
0527 SCL_H_SCALE_RATIO_C, dc_fixpt_u3d19(data->ratios.horz_c) << 5);
0528
0529 REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0,
0530 SCL_V_SCALE_RATIO_C, dc_fixpt_u3d19(data->ratios.vert_c) << 5);
0531
0532
0533
0534
0535 init_frac = dc_fixpt_u0d19(data->inits.h) << 5;
0536 init_int = dc_fixpt_floor(data->inits.h);
0537 REG_SET_2(SCL_HORZ_FILTER_INIT, 0,
0538 SCL_H_INIT_FRAC, init_frac,
0539 SCL_H_INIT_INT, init_int);
0540
0541 init_frac = dc_fixpt_u0d19(data->inits.h_c) << 5;
0542 init_int = dc_fixpt_floor(data->inits.h_c);
0543 REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0,
0544 SCL_H_INIT_FRAC_C, init_frac,
0545 SCL_H_INIT_INT_C, init_int);
0546
0547 init_frac = dc_fixpt_u0d19(data->inits.v) << 5;
0548 init_int = dc_fixpt_floor(data->inits.v);
0549 REG_SET_2(SCL_VERT_FILTER_INIT, 0,
0550 SCL_V_INIT_FRAC, init_frac,
0551 SCL_V_INIT_INT, init_int);
0552
0553 if (REG(SCL_VERT_FILTER_INIT_BOT)) {
0554 struct fixed31_32 bot = dc_fixpt_add(data->inits.v, data->ratios.vert);
0555
0556 init_frac = dc_fixpt_u0d19(bot) << 5;
0557 init_int = dc_fixpt_floor(bot);
0558 REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0,
0559 SCL_V_INIT_FRAC_BOT, init_frac,
0560 SCL_V_INIT_INT_BOT, init_int);
0561 }
0562
0563 init_frac = dc_fixpt_u0d19(data->inits.v_c) << 5;
0564 init_int = dc_fixpt_floor(data->inits.v_c);
0565 REG_SET_2(SCL_VERT_FILTER_INIT_C, 0,
0566 SCL_V_INIT_FRAC_C, init_frac,
0567 SCL_V_INIT_INT_C, init_int);
0568
0569 if (REG(SCL_VERT_FILTER_INIT_BOT_C)) {
0570 struct fixed31_32 bot = dc_fixpt_add(data->inits.v_c, data->ratios.vert_c);
0571
0572 init_frac = dc_fixpt_u0d19(bot) << 5;
0573 init_int = dc_fixpt_floor(bot);
0574 REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0,
0575 SCL_V_INIT_FRAC_BOT_C, init_frac,
0576 SCL_V_INIT_INT_BOT_C, init_int);
0577 }
0578 }
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591 static void dpp1_dscl_set_recout(struct dcn10_dpp *dpp,
0592 const struct rect *recout)
0593 {
0594 int visual_confirm_on = 0;
0595 unsigned short visual_confirm_rect_height = VISUAL_CONFIRM_RECT_HEIGHT_DEFAULT;
0596
0597 if (dpp->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE)
0598 visual_confirm_on = 1;
0599
0600
0601 if ((dpp->base.ctx->dc->debug.visual_confirm_rect_height >= VISUAL_CONFIRM_RECT_HEIGHT_MIN) &&
0602 (dpp->base.ctx->dc->debug.visual_confirm_rect_height <= VISUAL_CONFIRM_RECT_HEIGHT_MAX)) {
0603 visual_confirm_rect_height = dpp->base.ctx->dc->debug.visual_confirm_rect_height;
0604 }
0605
0606 REG_SET_2(RECOUT_START, 0,
0607
0608 RECOUT_START_X, recout->x,
0609
0610 RECOUT_START_Y, recout->y);
0611
0612 REG_SET_2(RECOUT_SIZE, 0,
0613
0614 RECOUT_WIDTH, recout->width,
0615
0616 RECOUT_HEIGHT, recout->height
0617 - visual_confirm_on * 2 * (dpp->base.inst + visual_confirm_rect_height));
0618 }
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630 void dpp1_dscl_set_scaler_manual_scale(struct dpp *dpp_base,
0631 const struct scaler_data *scl_data)
0632 {
0633 enum lb_memory_config lb_config;
0634 struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
0635 enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode(
0636 dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale);
0637 bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN
0638 && scl_data->format <= PIXEL_FORMAT_VIDEO_END;
0639
0640 if (memcmp(&dpp->scl_data, scl_data, sizeof(*scl_data)) == 0)
0641 return;
0642
0643 PERF_TRACE();
0644
0645 dpp->scl_data = *scl_data;
0646
0647 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl) {
0648 if (dscl_mode != DSCL_MODE_DSCL_BYPASS)
0649 dpp1_power_on_dscl(dpp_base, true);
0650 }
0651
0652
0653 REG_SET_3(DSCL_AUTOCAL, 0,
0654 AUTOCAL_MODE, AUTOCAL_MODE_OFF,
0655 AUTOCAL_NUM_PIPE, 0,
0656 AUTOCAL_PIPE_ID, 0);
0657
0658
0659 dpp1_dscl_set_recout(dpp, &scl_data->recout);
0660
0661
0662 REG_SET_2(MPC_SIZE, 0,
0663
0664 MPC_WIDTH, scl_data->h_active,
0665
0666 MPC_HEIGHT, scl_data->v_active);
0667
0668
0669 REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode);
0670
0671 if (dscl_mode == DSCL_MODE_DSCL_BYPASS) {
0672 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.dscl)
0673 dpp1_power_on_dscl(dpp_base, false);
0674 return;
0675 }
0676
0677
0678 lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data);
0679 dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config);
0680
0681 if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS)
0682 return;
0683
0684
0685 if (REG(SCL_BLACK_OFFSET)) {
0686 if (ycbcr)
0687 REG_SET_2(SCL_BLACK_OFFSET, 0,
0688 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y,
0689 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR);
0690 else
0691
0692 REG_SET_2(SCL_BLACK_OFFSET, 0,
0693 SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y,
0694 SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y);
0695 }
0696
0697
0698 dpp1_dscl_set_manual_ratio_init(dpp, scl_data);
0699
0700
0701 REG_SET_4(SCL_TAP_CONTROL, 0,
0702 SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1,
0703 SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1,
0704 SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1,
0705 SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1);
0706
0707 dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr);
0708 PERF_TRACE();
0709 }