static void dce_transform_set_scaler( struct transform *xfm, const struct scaler_data *data) { struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm); bool is_scaling_required; bool filter_updated = false; const uint16_t *coeffs_v, *coeffs_h; /*Use all three pieces of memory always*/ REG_SET_2(LB_MEMORY_CTRL, 0, LB_MEMORY_CONFIG, 0, LB_MEMORY_SIZE, xfm_dce->lb_memory_size); /* Clear SCL_F_SHARP_CONTROL value to 0 */ REG_WRITE(SCL_F_SHARP_CONTROL, 0); /* 1. Program overscan */ program_overscan(xfm_dce, data); /* 2. Program taps and configuration */ is_scaling_required = setup_scaling_configuration(xfm_dce, data); if (is_scaling_required) { /* 3. Calculate and program ratio, filter initialization */ struct scl_ratios_inits inits = { 0 }; calculate_inits(xfm_dce, data, &inits); program_scl_ratios_inits(xfm_dce, &inits); coeffs_v = get_filter_coeffs_16p(data->taps.v_taps, data->ratios.vert); coeffs_h = get_filter_coeffs_16p(data->taps.h_taps, data->ratios.horz); if (coeffs_v != xfm_dce->filter_v || coeffs_h != xfm_dce->filter_h) { /* 4. Program vertical filters */ if (xfm_dce->filter_v == NULL) REG_SET(SCL_VERT_FILTER_CONTROL, 0, SCL_V_2TAP_HARDCODE_COEF_EN, 0); program_multi_taps_filter( xfm_dce, data->taps.v_taps, coeffs_v, FILTER_TYPE_RGB_Y_VERTICAL); program_multi_taps_filter( xfm_dce, data->taps.v_taps, coeffs_v, FILTER_TYPE_ALPHA_VERTICAL); /* 5. Program horizontal filters */ if (xfm_dce->filter_h == NULL) REG_SET(SCL_HORZ_FILTER_CONTROL, 0, SCL_H_2TAP_HARDCODE_COEF_EN, 0); program_multi_taps_filter( xfm_dce, data->taps.h_taps, coeffs_h, FILTER_TYPE_RGB_Y_HORIZONTAL); program_multi_taps_filter( xfm_dce, data->taps.h_taps, coeffs_h, FILTER_TYPE_ALPHA_HORIZONTAL); xfm_dce->filter_v = coeffs_v; xfm_dce->filter_h = coeffs_h; filter_updated = true; } } /* 6. Program the viewport */ program_viewport(xfm_dce, &data->viewport); /* 7. Set bit to flip to new coefficient memory */ if (filter_updated) REG_UPDATE(SCL_UPDATE, SCL_COEF_UPDATE_COMPLETE, 1); REG_UPDATE(LB_DATA_FORMAT, ALPHA_EN, data->lb_params.alpha_en); }
static bool dce110_transform_v_set_scaler( struct transform *xfm, const struct scaler_data *data) { struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm); bool is_scaling_required = false; bool filter_updated = false; struct rect luma_viewport = {0}; struct rect chroma_viewport = {0}; struct dc_context *ctx = xfm->ctx; /* 1. Calculate viewport, viewport programming should happen after init * calculations as they may require an adjustment in the viewport. */ calculate_viewport(data, &luma_viewport, &chroma_viewport); /* 2. Program overscan */ program_overscan(xfm110, &data->overscan); /* 3. Program taps and configuration */ is_scaling_required = setup_scaling_configuration(xfm110, data); if (is_scaling_required) { /* 4. Calculate and program ratio, filter initialization */ struct sclv_ratios_inits inits = { 0 }; calculate_inits( xfm110, data, &inits, &luma_viewport, &chroma_viewport); program_scl_ratios_inits(xfm110, &inits); /*scaler coeff of 2-TAPS use hardware auto calculated value*/ /* 5. Program vertical filters */ if (data->taps.v_taps > 2) { program_two_taps_filter_vert(xfm110, false); if (!program_multi_taps_filter(xfm110, data, false)) { dal_logger_write(ctx->logger, LOG_MAJOR_DCP, LOG_MINOR_DCP_SCALER, "Failed vertical taps programming\n"); return false; } filter_updated = true; } else program_two_taps_filter_vert(xfm110, true); /* 6. Program horizontal filters */ if (data->taps.h_taps > 2) { program_two_taps_filter_horz(xfm110, false); if (!program_multi_taps_filter(xfm110, data, true)) { dal_logger_write(ctx->logger, LOG_MAJOR_DCP, LOG_MINOR_DCP_SCALER, "Failed horizontal taps programming\n"); return false; } filter_updated = true; } else program_two_taps_filter_horz(xfm110, true); } /* 7. Program the viewport */ program_viewport(xfm110, &luma_viewport, &chroma_viewport); /* 8. Set bit to flip to new coefficient memory */ if (filter_updated) set_coeff_update_complete(xfm110); return true; }