Commit 7a09f5be authored by Yue Hin Lau's avatar Yue Hin Lau Committed by Alex Deucher
Browse files

drm/amd/display: move regamma from opp to dpp for dce

parent 9b690ef3
Loading
Loading
Loading
Loading
+0 −237
Original line number Diff line number Diff line
@@ -92,242 +92,8 @@ enum {
 *
 *****************************************************************************
 */
static void regamma_config_regions_and_segments(
	struct dce110_opp *opp110,
	const struct pwl_params *params)
{
	const struct gamma_curve *curve;

	{
		REG_SET_2(REGAMMA_CNTLA_START_CNTL, 0,
			REGAMMA_CNTLA_EXP_REGION_START, params->arr_points[0].custom_float_x,
			REGAMMA_CNTLA_EXP_REGION_START_SEGMENT, 0);
	}
	{
		REG_SET(REGAMMA_CNTLA_SLOPE_CNTL, 0,
			REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE, params->arr_points[0].custom_float_slope);

	}
	{
		REG_SET(REGAMMA_CNTLA_END_CNTL1, 0,
			REGAMMA_CNTLA_EXP_REGION_END, params->arr_points[1].custom_float_x);
	}
	{
		REG_SET_2(REGAMMA_CNTLA_END_CNTL2, 0,
			REGAMMA_CNTLA_EXP_REGION_END_BASE, params->arr_points[1].custom_float_y,
			REGAMMA_CNTLA_EXP_REGION_END_SLOPE, params->arr_points[2].custom_float_slope);
	}

	curve = params->arr_curve_points;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_0_1, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_2_3, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_4_5, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_6_7, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_8_9, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_10_11, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_12_13, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_14_15, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
	}
}

static void program_pwl(
	struct dce110_opp *opp110,
	const struct pwl_params *params)
{
	uint32_t value;
	int retval;

	{
		uint8_t max_tries = 10;
		uint8_t counter = 0;

		/* Power on LUT memory */
		if (REG(DCFE_MEM_PWR_CTRL))
			REG_UPDATE(DCFE_MEM_PWR_CTRL,
				DCP_REGAMMA_MEM_PWR_DIS, 1);
		else
			REG_UPDATE(DCFE_MEM_LIGHT_SLEEP_CNTL,
				REGAMMA_LUT_LIGHT_SLEEP_DIS, 1);

		while (counter < max_tries) {
			if (REG(DCFE_MEM_PWR_STATUS)) {
				value = REG_READ(DCFE_MEM_PWR_STATUS);
				REG_GET(DCFE_MEM_PWR_STATUS,
						DCP_REGAMMA_MEM_PWR_STATE,
						&retval);

				if (retval == 0)
						break;
				++counter;
			} else {
				value = REG_READ(DCFE_MEM_LIGHT_SLEEP_CNTL);
				REG_GET(DCFE_MEM_LIGHT_SLEEP_CNTL,
						REGAMMA_LUT_MEM_PWR_STATE,
						&retval);

				if (retval == 0)
						break;
				++counter;
			}
		}

		if (counter == max_tries) {
			dm_logger_write(opp110->base.ctx->logger, LOG_WARNING,
				"%s: regamma lut was not powered on "
				"in a timely manner,"
				" programming still proceeds\n",
				__func__);
		}
	}

	REG_UPDATE(REGAMMA_LUT_WRITE_EN_MASK,
			REGAMMA_LUT_WRITE_EN_MASK, 7);

	REG_WRITE(REGAMMA_LUT_INDEX, 0);

	/* Program REGAMMA_LUT_DATA */
	{
		uint32_t i = 0;
		const struct pwl_result_data *rgb = params->rgb_resulted;

		while (i != params->hw_points_num) {

			REG_WRITE(REGAMMA_LUT_DATA, rgb->red_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->green_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->blue_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_red_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_green_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_blue_reg);

			++rgb;
			++i;
		}
	}

	/*  we are done with DCP LUT memory; re-enable low power mode */
	if (REG(DCFE_MEM_PWR_CTRL))
		REG_UPDATE(DCFE_MEM_PWR_CTRL,
			DCP_REGAMMA_MEM_PWR_DIS, 0);
	else
		REG_UPDATE(DCFE_MEM_LIGHT_SLEEP_CNTL,
			REGAMMA_LUT_LIGHT_SLEEP_DIS, 0);
}

bool dce110_opp_program_regamma_pwl(
	struct output_pixel_processor *opp,
	const struct pwl_params *params)
{
	struct dce110_opp *opp110 = TO_DCE110_OPP(opp);

	/* Setup regions */
	regamma_config_regions_and_segments(opp110, params);

	/* Program PWL */
	program_pwl(opp110, params);

	return true;
}

void dce110_opp_power_on_regamma_lut(
	struct output_pixel_processor *opp,
	bool power_on)
{
	struct dce110_opp *opp110 = TO_DCE110_OPP(opp);

	if (REG(DCFE_MEM_PWR_CTRL))
		REG_UPDATE_2(DCFE_MEM_PWR_CTRL,
			DCP_REGAMMA_MEM_PWR_DIS, power_on,
			DCP_LUT_MEM_PWR_DIS, power_on);
	else
		REG_UPDATE_2(DCFE_MEM_LIGHT_SLEEP_CNTL,
			REGAMMA_LUT_LIGHT_SLEEP_DIS, power_on,
			DCP_LUT_LIGHT_SLEEP_DIS, power_on);

}

void dce110_opp_set_regamma_mode(struct output_pixel_processor *opp,
		enum opp_regamma mode)
{
	struct dce110_opp *opp110 = TO_DCE110_OPP(opp);

	REG_SET(REGAMMA_CONTROL, 0,
			GRPH_REGAMMA_MODE, mode);
}

/**
 *	set_truncation
@@ -768,10 +534,7 @@ void dce110_opp_program_fmt(
/*****************************************/

static const struct opp_funcs funcs = {
	.opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
	.opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
	.opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
	.opp_set_regamma_mode = dce110_opp_set_regamma_mode,
	.opp_destroy = dce110_opp_destroy,
	.opp_program_fmt = dce110_opp_program_fmt,
	.opp_program_bit_depth_reduction = dce110_opp_program_bit_depth_reduction
+1 −112
Original line number Diff line number Diff line
@@ -41,22 +41,6 @@ enum dce110_opp_reg_type {
};

#define OPP_COMMON_REG_LIST_BASE(id) \
	SRI(REGAMMA_CNTLA_START_CNTL, DCP, id), \
	SRI(REGAMMA_CNTLA_SLOPE_CNTL, DCP, id), \
	SRI(REGAMMA_CNTLA_END_CNTL1, DCP, id), \
	SRI(REGAMMA_CNTLA_END_CNTL2, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_0_1, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_2_3, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_4_5, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_6_7, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_8_9, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_10_11, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_12_13, DCP, id), \
	SRI(REGAMMA_CNTLA_REGION_14_15, DCP, id), \
	SRI(REGAMMA_LUT_WRITE_EN_MASK, DCP, id), \
	SRI(REGAMMA_LUT_INDEX, DCP, id), \
	SRI(REGAMMA_LUT_DATA, DCP, id), \
	SRI(REGAMMA_CONTROL, DCP, id), \
	SRI(FMT_DYNAMIC_EXP_CNTL, FMT, id), \
	SRI(FMT_BIT_DEPTH_CONTROL, FMT, id), \
	SRI(FMT_CONTROL, FMT, id), \
@@ -70,31 +54,24 @@ enum dce110_opp_reg_type {

#define OPP_DCE_80_REG_LIST(id) \
	OPP_COMMON_REG_LIST_BASE(id), \
	SRI(DCFE_MEM_LIGHT_SLEEP_CNTL, CRTC, id), \
	SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id)

#define OPP_DCE_100_REG_LIST(id) \
	OPP_COMMON_REG_LIST_BASE(id), \
	SRI(DCFE_MEM_PWR_CTRL, CRTC, id), \
	SRI(DCFE_MEM_PWR_STATUS, CRTC, id), \
	SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id)

#define OPP_DCE_110_REG_LIST(id) \
	OPP_COMMON_REG_LIST_BASE(id), \
	SRI(DCFE_MEM_PWR_CTRL, DCFE, id), \
	SRI(DCFE_MEM_PWR_STATUS, DCFE, id), \
	SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id)

#define OPP_DCE_112_REG_LIST(id) \
	OPP_COMMON_REG_LIST_BASE(id), \
	SRI(DCFE_MEM_PWR_CTRL, DCFE, id), \
	SRI(DCFE_MEM_PWR_STATUS, DCFE, id), \
	SRI(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, FMT, id), \
	SRI(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, FMT, id), \
@@ -102,26 +79,12 @@ enum dce110_opp_reg_type {

#define OPP_DCE_120_REG_LIST(id) \
	OPP_COMMON_REG_LIST_BASE(id), \
	SRI(DCFE_MEM_PWR_CTRL, DCFE, id), \
	SRI(DCFE_MEM_PWR_STATUS, DCFE, id), \
	SRI(CONTROL, FMT_MEMORY, id)

#define OPP_SF(reg_name, field_name, post_fix)\
	.field_name = reg_name ## __ ## field_name ## post_fix

#define OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)\
	OPP_SF(REGAMMA_CNTLA_START_CNTL, REGAMMA_CNTLA_EXP_REGION_START, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_START_CNTL, REGAMMA_CNTLA_EXP_REGION_START_SEGMENT, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_SLOPE_CNTL, REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_END_CNTL1, REGAMMA_CNTLA_EXP_REGION_END, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_END_CNTL2, REGAMMA_CNTLA_EXP_REGION_END_BASE, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_END_CNTL2, REGAMMA_CNTLA_EXP_REGION_END_SLOPE, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, mask_sh),\
	OPP_SF(REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, mask_sh),\
	OPP_SF(REGAMMA_LUT_WRITE_EN_MASK, REGAMMA_LUT_WRITE_EN_MASK, mask_sh),\
	OPP_SF(REGAMMA_CONTROL, GRPH_REGAMMA_MODE, mask_sh),\
	OPP_SF(FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN, mask_sh),\
	OPP_SF(FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE, mask_sh),\
	OPP_SF(FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh),\
@@ -160,27 +123,18 @@ enum dce110_opp_reg_type {

#define OPP_COMMON_MASK_SH_LIST_DCE_110(mask_sh)\
	OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
	OPP_SF(DCFE_MEM_PWR_CTRL, DCP_REGAMMA_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_PWR_STATUS, DCP_REGAMMA_MEM_PWR_STATE, mask_sh),\
	OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh),\
	OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh),\
	OPP_SF(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, mask_sh)

#define OPP_COMMON_MASK_SH_LIST_DCE_100(mask_sh)\
	OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
	OPP_SF(DCFE_MEM_PWR_CTRL, DCP_REGAMMA_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_PWR_STATUS, DCP_REGAMMA_MEM_PWR_STATE, mask_sh),\
	OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh),\
	OPP_SF(FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh),\
	OPP_SF(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, mask_sh)

#define OPP_COMMON_MASK_SH_LIST_DCE_112(mask_sh)\
	OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
	OPP_SF(DCFE_MEM_PWR_CTRL, DCP_REGAMMA_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_PWR_STATUS, DCP_REGAMMA_MEM_PWR_STATE, mask_sh),\
	OPP_SF(FMT_MEMORY0_CONTROL, FMT420_MEM0_SOURCE_SEL, mask_sh),\
	OPP_SF(FMT_MEMORY0_CONTROL, FMT420_MEM0_PWR_FORCE, mask_sh),\
	OPP_SF(FMT_CONTROL, FMT_420_PIXEL_PHASE_LOCKED_CLEAR, mask_sh),\
@@ -191,27 +145,9 @@ enum dce110_opp_reg_type {
	OPP_SF(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, mask_sh)

#define OPP_COMMON_MASK_SH_LIST_DCE_80(mask_sh)\
	OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\
	OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, REGAMMA_LUT_LIGHT_SLEEP_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, DCP_LUT_LIGHT_SLEEP_DIS, mask_sh),\
	OPP_SF(DCFE_MEM_LIGHT_SLEEP_CNTL, REGAMMA_LUT_MEM_PWR_STATE, mask_sh)
	OPP_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)

#define OPP_COMMON_MASK_SH_LIST_DCE_120(mask_sh)\
	OPP_SF(DCFE0_DCFE_MEM_PWR_CTRL, DCP_REGAMMA_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCFE0_DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_START_CNTL, REGAMMA_CNTLA_EXP_REGION_START, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_START_CNTL, REGAMMA_CNTLA_EXP_REGION_START_SEGMENT, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_SLOPE_CNTL, REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_END_CNTL1, REGAMMA_CNTLA_EXP_REGION_END, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_END_CNTL2, REGAMMA_CNTLA_EXP_REGION_END_BASE, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_END_CNTL2, REGAMMA_CNTLA_EXP_REGION_END_SLOPE, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CNTLA_REGION_0_1, REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, mask_sh),\
	OPP_SF(DCFE0_DCFE_MEM_PWR_STATUS, DCP_REGAMMA_MEM_PWR_STATE, mask_sh),\
	OPP_SF(DCP0_REGAMMA_LUT_WRITE_EN_MASK, REGAMMA_LUT_WRITE_EN_MASK, mask_sh),\
	OPP_SF(DCP0_REGAMMA_CONTROL, GRPH_REGAMMA_MODE, mask_sh),\
	OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN, mask_sh),\
	OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE, mask_sh),\
	OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh),\
@@ -257,24 +193,6 @@ enum dce110_opp_reg_type {
	OPP_SF(FMT0_FMT_CONTROL, FMT_CBCR_BIT_REDUCTION_BYPASS, mask_sh)

#define OPP_REG_FIELD_LIST(type) \
	type DCP_REGAMMA_MEM_PWR_DIS; \
	type DCP_LUT_MEM_PWR_DIS; \
	type REGAMMA_LUT_LIGHT_SLEEP_DIS; \
	type DCP_LUT_LIGHT_SLEEP_DIS; \
	type REGAMMA_CNTLA_EXP_REGION_START; \
	type REGAMMA_CNTLA_EXP_REGION_START_SEGMENT; \
	type REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE; \
	type REGAMMA_CNTLA_EXP_REGION_END; \
	type REGAMMA_CNTLA_EXP_REGION_END_BASE; \
	type REGAMMA_CNTLA_EXP_REGION_END_SLOPE; \
	type REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET; \
	type REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS; \
	type REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET; \
	type REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS; \
	type DCP_REGAMMA_MEM_PWR_STATE; \
	type REGAMMA_LUT_MEM_PWR_STATE; \
	type REGAMMA_LUT_WRITE_EN_MASK; \
	type GRPH_REGAMMA_MODE; \
	type FMT_DYNAMIC_EXP_EN; \
	type FMT_DYNAMIC_EXP_MODE; \
	type FMT_TRUNCATE_EN; \
@@ -327,25 +245,6 @@ struct dce_opp_mask {
};

struct dce_opp_registers {
	uint32_t DCFE_MEM_PWR_CTRL;
	uint32_t DCFE_MEM_LIGHT_SLEEP_CNTL;
	uint32_t REGAMMA_CNTLA_START_CNTL;
	uint32_t REGAMMA_CNTLA_SLOPE_CNTL;
	uint32_t REGAMMA_CNTLA_END_CNTL1;
	uint32_t REGAMMA_CNTLA_END_CNTL2;
	uint32_t REGAMMA_CNTLA_REGION_0_1;
	uint32_t REGAMMA_CNTLA_REGION_2_3;
	uint32_t REGAMMA_CNTLA_REGION_4_5;
	uint32_t REGAMMA_CNTLA_REGION_6_7;
	uint32_t REGAMMA_CNTLA_REGION_8_9;
	uint32_t REGAMMA_CNTLA_REGION_10_11;
	uint32_t REGAMMA_CNTLA_REGION_12_13;
	uint32_t REGAMMA_CNTLA_REGION_14_15;
	uint32_t REGAMMA_LUT_WRITE_EN_MASK;
	uint32_t REGAMMA_LUT_INDEX;
	uint32_t DCFE_MEM_PWR_STATUS;
	uint32_t REGAMMA_LUT_DATA;
	uint32_t REGAMMA_CONTROL;
	uint32_t FMT_DYNAMIC_EXP_CNTL;
	uint32_t FMT_BIT_DEPTH_CONTROL;
	uint32_t FMT_CONTROL;
@@ -382,17 +281,7 @@ bool dce110_opp_construct(struct dce110_opp *opp110,

void dce110_opp_destroy(struct output_pixel_processor **opp);

/* REGAMMA RELATED */
void dce110_opp_power_on_regamma_lut(
	struct output_pixel_processor *opp,
	bool power_on);

bool dce110_opp_program_regamma_pwl(
	struct output_pixel_processor *opp,
	const struct pwl_params *params);

void dce110_opp_set_regamma_mode(struct output_pixel_processor *opp,
		enum opp_regamma mode);

/* FORMATTER RELATED */
void dce110_opp_program_bit_depth_reduction(
+240 −0
Original line number Diff line number Diff line
@@ -1177,7 +1177,244 @@ void dce110_opp_set_csc_default(
		default_adjust->out_color_space);
}

static void program_pwl(
	struct dce_transform *xfm_dce,
	const struct pwl_params *params)
{
	uint32_t value;
	int retval;

	{
		uint8_t max_tries = 10;
		uint8_t counter = 0;

		/* Power on LUT memory */
		if (REG(DCFE_MEM_PWR_CTRL))
			REG_UPDATE(DCFE_MEM_PWR_CTRL,
				DCP_REGAMMA_MEM_PWR_DIS, 1);
		else
			REG_UPDATE(DCFE_MEM_LIGHT_SLEEP_CNTL,
				REGAMMA_LUT_LIGHT_SLEEP_DIS, 1);

		while (counter < max_tries) {
			if (REG(DCFE_MEM_PWR_STATUS)) {
				value = REG_READ(DCFE_MEM_PWR_STATUS);
				REG_GET(DCFE_MEM_PWR_STATUS,
						DCP_REGAMMA_MEM_PWR_STATE,
						&retval);

				if (retval == 0)
						break;
				++counter;
			} else {
				value = REG_READ(DCFE_MEM_LIGHT_SLEEP_CNTL);
				REG_GET(DCFE_MEM_LIGHT_SLEEP_CNTL,
						REGAMMA_LUT_MEM_PWR_STATE,
						&retval);

				if (retval == 0)
						break;
				++counter;
			}
		}

		if (counter == max_tries) {
			dm_logger_write(xfm_dce->base.ctx->logger, LOG_WARNING,
				"%s: regamma lut was not powered on "
				"in a timely manner,"
				" programming still proceeds\n",
				__func__);
		}
	}

	REG_UPDATE(REGAMMA_LUT_WRITE_EN_MASK,
			REGAMMA_LUT_WRITE_EN_MASK, 7);

	REG_WRITE(REGAMMA_LUT_INDEX, 0);

	/* Program REGAMMA_LUT_DATA */
	{
		uint32_t i = 0;
		const struct pwl_result_data *rgb = params->rgb_resulted;

		while (i != params->hw_points_num) {

			REG_WRITE(REGAMMA_LUT_DATA, rgb->red_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->green_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->blue_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_red_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_green_reg);
			REG_WRITE(REGAMMA_LUT_DATA, rgb->delta_blue_reg);

			++rgb;
			++i;
		}
	}

	/*  we are done with DCP LUT memory; re-enable low power mode */
	if (REG(DCFE_MEM_PWR_CTRL))
		REG_UPDATE(DCFE_MEM_PWR_CTRL,
			DCP_REGAMMA_MEM_PWR_DIS, 0);
	else
		REG_UPDATE(DCFE_MEM_LIGHT_SLEEP_CNTL,
			REGAMMA_LUT_LIGHT_SLEEP_DIS, 0);
}

static void regamma_config_regions_and_segments(
	struct dce_transform *xfm_dce,
	const struct pwl_params *params)
{
	const struct gamma_curve *curve;

	{
		REG_SET_2(REGAMMA_CNTLA_START_CNTL, 0,
			REGAMMA_CNTLA_EXP_REGION_START, params->arr_points[0].custom_float_x,
			REGAMMA_CNTLA_EXP_REGION_START_SEGMENT, 0);
	}
	{
		REG_SET(REGAMMA_CNTLA_SLOPE_CNTL, 0,
			REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE, params->arr_points[0].custom_float_slope);

	}
	{
		REG_SET(REGAMMA_CNTLA_END_CNTL1, 0,
			REGAMMA_CNTLA_EXP_REGION_END, params->arr_points[1].custom_float_x);
	}
	{
		REG_SET_2(REGAMMA_CNTLA_END_CNTL2, 0,
			REGAMMA_CNTLA_EXP_REGION_END_BASE, params->arr_points[1].custom_float_y,
			REGAMMA_CNTLA_EXP_REGION_END_SLOPE, params->arr_points[2].custom_float_slope);
	}

	curve = params->arr_curve_points;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_0_1, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_2_3, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_4_5, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_6_7, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_8_9, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_10_11, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_12_13, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);

	}

	curve += 2;

	{
		REG_SET_4(REGAMMA_CNTLA_REGION_14_15, 0,
			REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
			REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
			REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
			REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
	}
}



bool dce110_opp_program_regamma_pwl(
	struct transform *xfm,
	const struct pwl_params *params)
{
	struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);

	/* Setup regions */
	regamma_config_regions_and_segments(xfm_dce, params);

	/* Program PWL */
	program_pwl(xfm_dce, params);

	return true;
}

void dce110_opp_power_on_regamma_lut(
	struct transform *xfm,
	bool power_on)
{
	struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);

	if (REG(DCFE_MEM_PWR_CTRL))
		REG_UPDATE_2(DCFE_MEM_PWR_CTRL,
			DCP_REGAMMA_MEM_PWR_DIS, power_on,
			DCP_LUT_MEM_PWR_DIS, power_on);
	else
		REG_UPDATE_2(DCFE_MEM_LIGHT_SLEEP_CNTL,
			REGAMMA_LUT_LIGHT_SLEEP_DIS, power_on,
			DCP_LUT_LIGHT_SLEEP_DIS, power_on);

}

void dce110_opp_set_regamma_mode(struct transform *xfm,
		enum opp_regamma mode)
{
	struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);

	REG_SET(REGAMMA_CONTROL, 0,
			GRPH_REGAMMA_MODE, mode);
}

static const struct transform_funcs dce_transform_funcs = {
	.transform_reset = dce_transform_reset,
@@ -1187,6 +1424,9 @@ static const struct transform_funcs dce_transform_funcs = {
		dce_transform_set_gamut_remap,
	.opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
	.opp_set_csc_default = dce110_opp_set_csc_default,
	.opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
	.opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
	.opp_set_regamma_mode = dce110_opp_set_regamma_mode,
	.transform_set_pixel_storage_depth =
		dce_transform_set_pixel_storage_depth,
	.transform_get_optimal_number_of_taps =
+88 −0

File changed.

Preview size limit exceeded, changes collapsed.

+9 −9
Original line number Diff line number Diff line
@@ -625,26 +625,26 @@ static bool dce110_set_output_transfer_func(
	struct pipe_ctx *pipe_ctx,
	const struct dc_stream *stream)
{
	struct output_pixel_processor *opp = pipe_ctx->opp;
	struct transform *xfm = pipe_ctx->xfm;

	opp->funcs->opp_power_on_regamma_lut(opp, true);
	opp->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;
	xfm->funcs->opp_power_on_regamma_lut(xfm, true);
	xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM;

	if (stream->out_transfer_func &&
		stream->out_transfer_func->type ==
			TF_TYPE_PREDEFINED &&
		stream->out_transfer_func->tf ==
			TRANSFER_FUNCTION_SRGB) {
		opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB);
		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB);
	} else if (dce110_translate_regamma_to_hw_format(
				stream->out_transfer_func, &opp->regamma_params)) {
			opp->funcs->opp_program_regamma_pwl(opp, &opp->regamma_params);
			opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER);
				stream->out_transfer_func, &xfm->regamma_params)) {
		xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params);
		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER);
	} else {
		opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS);
		xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS);
	}

	opp->funcs->opp_power_on_regamma_lut(opp, false);
	xfm->funcs->opp_power_on_regamma_lut(xfm, false);

	return true;
}
Loading