コード例 #1
0
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;
}
コード例 #2
0
ファイル: dce_transform.c プロジェクト: AlexShiLucky/linux
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);
}
コード例 #3
0
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;
}