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; }
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); }
enum hwss_result dal_hw_sequencer_set_overscan_adj( struct hw_sequencer *hws, struct hw_path_mode_set *set, struct hw_underscan_adjustment_data *hw_underscan) { struct hwss_build_params *build_params = NULL; union hwss_build_params_mask params_mask; struct hw_underscan_parameters underscan_params; const struct hw_underscan_adjustment *value; if (set == NULL || hw_underscan->hw_adj_id != HW_ADJUSTMENT_ID_OVERSCAN) return HWSS_RESULT_ERROR; value = &hw_underscan->hw_underscan_adj; if (!value) return HWSS_RESULT_ERROR; dal_memset(&underscan_params, 0, sizeof(underscan_params)); underscan_params.hw_path_mode = get_required_mode_path( set, HW_PATH_ACTION_SET_ADJUSTMENT, &underscan_params.path_id); if (!underscan_params.hw_path_mode) return HWSS_RESULT_ERROR; params_mask.all = 0; params_mask.bits.SCALING_TAPS = true; params_mask.bits.PLL_SETTINGS = true; params_mask.bits.MIN_CLOCKS = true; params_mask.bits.WATERMARK = true; params_mask.bits.BANDWIDTH = true; params_mask.bits.LINE_BUFFER = true; build_params = dal_hw_sequencer_prepare_path_parameters( hws, set, params_mask, false); if (NULL == build_params) return HWSS_RESULT_ERROR; underscan_params.path_set = set; underscan_params.pll_setting_array = build_params->pll_settings_params; underscan_params.watermark_input_array = build_params->wm_input_params; underscan_params.min_clk_array = build_params->min_clock_params; underscan_params.line_buffer_array = build_params->line_buffer_params[underscan_params.path_id]; underscan_params.taps = build_params->scaling_taps_params[underscan_params.path_id]; underscan_params.mini_clk_result = build_params->min_clock_result; underscan_params.scale_ratio_hp_factor.adjust = value->deflicker.hp_factor; underscan_params.scale_ratio_hp_factor.divider = value->deflicker.hp_divider; underscan_params.scale_ratio_lp_factor.adjust = value->deflicker.lp_factor; underscan_params.scale_ratio_lp_factor.divider = value->deflicker.lp_divider; underscan_params.sharp_gain.sharpness = value->deflicker.sharpness; underscan_params.sharp_gain.enable_sharpening = value->deflicker.enable_sharpening; if (program_overscan( hws, set, &underscan_params, build_params, underscan_params.hw_path_mode->display_path, true, build_params->params_num) != HWSS_RESULT_OK) { dal_hw_sequencer_free_path_parameters(build_params); return HWSS_RESULT_ERROR; } dal_hw_sequencer_free_path_parameters(build_params); return HWSS_RESULT_OK; }