diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules')
5 files changed, 623 insertions, 265 deletions
| diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index 479b77c2e89e..0fbc8fbc3541 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -823,7 +823,7 @@ static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma,  	bool is_clipped = false;  	struct fixed31_32 sdr_white_level; -	if (fs_params == NULL || fs_params->max_content == 0 || +	if (fs_params->max_content == 0 ||  			fs_params->max_display == 0)  		return false; @@ -1508,7 +1508,7 @@ static bool map_regamma_hw_to_x_user(  	struct hw_x_point *coords = coords_x;  	const struct pwl_float_data_ex *regamma = rgb_regamma; -	if (mapUserRamp) { +	if (ramp && mapUserRamp) {  		copy_rgb_regamma_to_coordinates_x(coords,  				hw_points_num,  				rgb_regamma); @@ -1545,7 +1545,7 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,  	struct pwl_float_data *rgb_user = NULL;  	struct pwl_float_data_ex *rgb_regamma = NULL; -	struct gamma_pixel *axix_x = NULL; +	struct gamma_pixel *axis_x = NULL;  	struct pixel_gamma_point *coeff = NULL;  	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;  	bool ret = false; @@ -1555,47 +1555,54 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,  	/* we can use hardcoded curve for plain SRGB TF */  	if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true && -			output_tf->tf == TRANSFER_FUNCTION_SRGB && -			(ramp->is_identity || (!mapUserRamp && ramp->type == GAMMA_RGB_256))) -		return true; +			output_tf->tf == TRANSFER_FUNCTION_SRGB) { +		if (ramp == NULL) +			return true; +		if (ramp->is_identity || (!mapUserRamp && ramp->type == GAMMA_RGB_256)) +			return true; +	}  	output_tf->type = TF_TYPE_DISTRIBUTED_POINTS; -	rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, +	if (ramp && (mapUserRamp || ramp->type != GAMMA_RGB_256)) { +		rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,  			    sizeof(*rgb_user),  			    GFP_KERNEL); -	if (!rgb_user) -		goto rgb_user_alloc_fail; +		if (!rgb_user) +			goto rgb_user_alloc_fail; + +		axis_x = kvcalloc(ramp->num_entries + 3, sizeof(*axis_x), +				GFP_KERNEL); +		if (!axis_x) +			goto axis_x_alloc_fail; + +		dividers.divider1 = dc_fixpt_from_fraction(3, 2); +		dividers.divider2 = dc_fixpt_from_int(2); +		dividers.divider3 = dc_fixpt_from_fraction(5, 2); + +		build_evenly_distributed_points( +				axis_x, +				ramp->num_entries, +				dividers); + +		if (ramp->type == GAMMA_RGB_256 && mapUserRamp) +			scale_gamma(rgb_user, ramp, dividers); +		else if (ramp->type == GAMMA_RGB_FLOAT_1024) +			scale_gamma_dx(rgb_user, ramp, dividers); +	} +  	rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,  			       sizeof(*rgb_regamma),  			       GFP_KERNEL);  	if (!rgb_regamma)  		goto rgb_regamma_alloc_fail; -	axix_x = kvcalloc(ramp->num_entries + 3, sizeof(*axix_x), -			  GFP_KERNEL); -	if (!axix_x) -		goto axix_x_alloc_fail; +  	coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),  			 GFP_KERNEL);  	if (!coeff)  		goto coeff_alloc_fail; -	dividers.divider1 = dc_fixpt_from_fraction(3, 2); -	dividers.divider2 = dc_fixpt_from_int(2); -	dividers.divider3 = dc_fixpt_from_fraction(5, 2); -  	tf = output_tf->tf; - -	build_evenly_distributed_points( -			axix_x, -			ramp->num_entries, -			dividers); - -	if (ramp->type == GAMMA_RGB_256 && mapUserRamp) -		scale_gamma(rgb_user, ramp, dividers); -	else if (ramp->type == GAMMA_RGB_FLOAT_1024) -		scale_gamma_dx(rgb_user, ramp, dividers); -  	if (tf == TRANSFER_FUNCTION_PQ) {  		tf_pts->end_exponent = 7;  		tf_pts->x_point_at_y1_red = 125; @@ -1623,22 +1630,22 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,  				coordinates_x, tf == TRANSFER_FUNCTION_SRGB ? true:false);  	}  	map_regamma_hw_to_x_user(ramp, coeff, rgb_user, -			coordinates_x, axix_x, rgb_regamma, +			coordinates_x, axis_x, rgb_regamma,  			MAX_HW_POINTS, tf_pts, -			(mapUserRamp || ramp->type != GAMMA_RGB_256) && -			ramp->type != GAMMA_CS_TFM_1D); +			(mapUserRamp || (ramp && ramp->type != GAMMA_RGB_256)) && +			(ramp && ramp->type != GAMMA_CS_TFM_1D)); -	if (ramp->type == GAMMA_CS_TFM_1D) +	if (ramp && ramp->type == GAMMA_CS_TFM_1D)  		apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);  	ret = true;  	kvfree(coeff);  coeff_alloc_fail: -	kvfree(axix_x); -axix_x_alloc_fail:  	kvfree(rgb_regamma);  rgb_regamma_alloc_fail: +	kvfree(axis_x); +axis_x_alloc_fail:  	kvfree(rgb_user);  rgb_user_alloc_fail:  	return ret; @@ -1758,69 +1765,85 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,  {  	struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;  	struct dividers dividers; -  	struct pwl_float_data *rgb_user = NULL;  	struct pwl_float_data_ex *curve = NULL;  	struct gamma_pixel *axis_x = NULL;  	struct pixel_gamma_point *coeff = NULL;  	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; +	uint32_t i;  	bool ret = false;  	if (input_tf->type == TF_TYPE_BYPASS)  		return false; -	/* we can use hardcoded curve for plain SRGB TF */ +	/* we can use hardcoded curve for plain SRGB TF +	 * If linear, it's bypass if on user ramp +	 */  	if (input_tf->type == TF_TYPE_PREDEFINED && -			input_tf->tf == TRANSFER_FUNCTION_SRGB && -			(!mapUserRamp && -			(ramp->type == GAMMA_RGB_256 || ramp->num_entries == 0))) +			(input_tf->tf == TRANSFER_FUNCTION_SRGB || +					input_tf->tf == TRANSFER_FUNCTION_LINEAR) && +					!mapUserRamp)  		return true;  	input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; -	rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, -			    sizeof(*rgb_user), -			    GFP_KERNEL); -	if (!rgb_user) -		goto rgb_user_alloc_fail; +	if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) { +		rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, +				sizeof(*rgb_user), +				GFP_KERNEL); +		if (!rgb_user) +			goto rgb_user_alloc_fail; + +		axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x), +				GFP_KERNEL); +		if (!axis_x) +			goto axis_x_alloc_fail; + +		dividers.divider1 = dc_fixpt_from_fraction(3, 2); +		dividers.divider2 = dc_fixpt_from_int(2); +		dividers.divider3 = dc_fixpt_from_fraction(5, 2); + +		build_evenly_distributed_points( +				axis_x, +				ramp->num_entries, +				dividers); + +		scale_gamma(rgb_user, ramp, dividers); +	} +  	curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve), -			 GFP_KERNEL); +			GFP_KERNEL);  	if (!curve)  		goto curve_alloc_fail; -	axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x), -			  GFP_KERNEL); -	if (!axis_x) -		goto axis_x_alloc_fail; +  	coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff), -			 GFP_KERNEL); +			GFP_KERNEL);  	if (!coeff)  		goto coeff_alloc_fail; -	dividers.divider1 = dc_fixpt_from_fraction(3, 2); -	dividers.divider2 = dc_fixpt_from_int(2); -	dividers.divider3 = dc_fixpt_from_fraction(5, 2); -  	tf = input_tf->tf; -	build_evenly_distributed_points( -			axis_x, -			ramp->num_entries, -			dividers); - -	if (ramp->type == GAMMA_RGB_256 && mapUserRamp) -		scale_gamma(rgb_user, ramp, dividers); -	else if (ramp->type == GAMMA_RGB_FLOAT_1024) -		scale_gamma_dx(rgb_user, ramp, dividers); -  	if (tf == TRANSFER_FUNCTION_PQ)  		build_de_pq(curve,  				MAX_HW_POINTS,  				coordinates_x); -	else +	else if (tf == TRANSFER_FUNCTION_SRGB || +			tf == TRANSFER_FUNCTION_BT709)  		build_degamma(curve,  				MAX_HW_POINTS,  				coordinates_x, -				tf == TRANSFER_FUNCTION_SRGB ? true:false); +				tf == TRANSFER_FUNCTION_SRGB ? true : false); +	else if (tf == TRANSFER_FUNCTION_LINEAR) { +		// just copy coordinates_x into curve +		i = 0; +		while (i != MAX_HW_POINTS + 1) { +			curve[i].r = coordinates_x[i].x; +			curve[i].g = curve[i].r; +			curve[i].b = curve[i].r; +			i++; +		} +	} else +		goto invalid_tf_fail;  	tf_pts->end_exponent = 0;  	tf_pts->x_point_at_y1_red = 1; @@ -1830,23 +1853,21 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,  	map_regamma_hw_to_x_user(ramp, coeff, rgb_user,  			coordinates_x, axis_x, curve,  			MAX_HW_POINTS, tf_pts, -			mapUserRamp && ramp->type != GAMMA_CUSTOM); -	if (ramp->type == GAMMA_CUSTOM) -		apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts); +			mapUserRamp && ramp && ramp->type == GAMMA_RGB_256);  	ret = true; +invalid_tf_fail:  	kvfree(coeff);  coeff_alloc_fail: -	kvfree(axis_x); -axis_x_alloc_fail:  	kvfree(curve);  curve_alloc_fail: +	kvfree(axis_x); +axis_x_alloc_fail:  	kvfree(rgb_user);  rgb_user_alloc_fail:  	return ret; -  } diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 1544ed3f1747..94a84bc57c7a 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -108,8 +108,8 @@ static unsigned int calc_duration_in_us_from_v_total(  {  	unsigned int duration_in_us =  			(unsigned int)(div64_u64(((unsigned long long)(v_total) -				* 1000) * stream->timing.h_total, -					stream->timing.pix_clk_khz)); +				* 10000) * stream->timing.h_total, +					stream->timing.pix_clk_100hz));  	return duration_in_us;  } @@ -126,7 +126,7 @@ static unsigned int calc_v_total_from_refresh(  					refresh_in_uhz)));  	v_total = div64_u64(div64_u64(((unsigned long long)( -			frame_duration_in_ns) * stream->timing.pix_clk_khz), +			frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),  			stream->timing.h_total), 1000000);  	/* v_total cannot be less than nominal */ @@ -152,7 +152,7 @@ static unsigned int calc_v_total_from_duration(  		duration_in_us = vrr->max_duration_in_us;  	v_total = div64_u64(div64_u64(((unsigned long long)( -				duration_in_us) * stream->timing.pix_clk_khz), +				duration_in_us) * (stream->timing.pix_clk_100hz / 10)),  				stream->timing.h_total), 1000);  	/* v_total cannot be less than nominal */ @@ -227,7 +227,7 @@ static void update_v_total_for_static_ramp(  	}  	v_total = div64_u64(div64_u64(((unsigned long long)( -			current_duration_in_us) * stream->timing.pix_clk_khz), +			current_duration_in_us) * (stream->timing.pix_clk_100hz / 10)),  				stream->timing.h_total), 1000);  	in_out_vrr->adjust.v_total_min = v_total; @@ -461,6 +461,26 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,  	return false;  } +static void build_vrr_infopacket_header_vtem(enum signal_type signal, +		struct dc_info_packet *infopacket) +{ +	// HEADER + +	// HB0, HB1, HB2 indicates PacketType VTEMPacket +	infopacket->hb0 = 0x7F; +	infopacket->hb1 = 0xC0; +	infopacket->hb2 = 0x00; +	/* HB3 Bit Fields +	 * Reserved :1 = 0 +	 * Sync     :1 = 0 +	 * VFR      :1 = 1 +	 * Ds_Type  :2 = 0 +	 * End      :1 = 0 +	 * New      :1 = 0 +	 */ +	infopacket->hb3 = 0x20; +} +  static void build_vrr_infopacket_header_v1(enum signal_type signal,  		struct dc_info_packet *infopacket,  		unsigned int *payload_size) @@ -559,6 +579,54 @@ static void build_vrr_infopacket_header_v2(enum signal_type signal,  	}  } +static void build_vrr_vtem_infopacket_data(const struct dc_stream_state *stream, +		const struct mod_vrr_params *vrr, +		struct dc_info_packet *infopacket) +{ +	/* dc_info_packet to VtemPacket Translation of Bit-fields, +	 * SB[6] +	 * unsigned char VRR_EN        :1 +	 * unsigned char M_CONST       :1 +	 * unsigned char Reserved2     :2 +	 * unsigned char FVA_Factor_M1 :4 +	 * SB[7] +	 * unsigned char Base_Vfront   :8 +	 * SB[8] +	 * unsigned char Base_Refresh_Rate_98 :2 +	 * unsigned char RB                   :1 +	 * unsigned char Reserved3            :5 +	 * SB[9] +	 * unsigned char Base_RefreshRate_07  :8 +	 */ +	unsigned int fieldRateInHz; + +	if (vrr->state == VRR_STATE_ACTIVE_VARIABLE || +				vrr->state == VRR_STATE_ACTIVE_FIXED){ +		infopacket->sb[6] |= 0x80; //VRR_EN Bit = 1 +	} else { +		infopacket->sb[6] &= 0x7F; //VRR_EN Bit = 0 +	} + +	if (!stream->timing.vic) { +		infopacket->sb[7] = stream->timing.v_front_porch; + +		/* TODO: In dal2, we check mode flags for a reduced blanking timing. +		 * Need a way to relay that information to this function. +		 * if("ReducedBlanking") +		 * { +		 *   infopacket->sb[8] |= 0x20; //Set 3rd bit to 1 +		 * } +		 */ +		fieldRateInHz = (stream->timing.pix_clk_100hz * 100)/ +				(stream->timing.h_total * stream->timing.v_total); + +		infopacket->sb[8] |= ((fieldRateInHz & 0x300) >> 2); +		infopacket->sb[9] |= fieldRateInHz & 0xFF; + +	} +	infopacket->valid = true; +} +  static void build_vrr_infopacket_data(const struct mod_vrr_params *vrr,  		struct dc_info_packet *infopacket)  { @@ -672,6 +740,19 @@ static void build_vrr_infopacket_v2(enum signal_type signal,  	infopacket->valid = true;  } +static void build_vrr_infopacket_vtem(const struct dc_stream_state *stream, +		const struct mod_vrr_params *vrr, +		struct dc_info_packet *infopacket) +{ +	//VTEM info packet for HdmiVrr + +	//VTEM Packet is structured differently +	build_vrr_infopacket_header_vtem(stream->signal, infopacket); +	build_vrr_vtem_infopacket_data(stream, vrr, infopacket); + +	infopacket->valid = true; +} +  void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,  		const struct dc_stream_state *stream,  		const struct mod_vrr_params *vrr, @@ -679,18 +760,21 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,  		const enum color_transfer_func *app_tf,  		struct dc_info_packet *infopacket)  { -	/* SPD info packet for FreeSync */ - -	/* Check if Freesync is supported. Return if false. If true, +	/* SPD info packet for FreeSync +	 * VTEM info packet for HdmiVRR +	 * Check if Freesync is supported. Return if false. If true,  	 * set the corresponding bit in the info packet  	 */ -	if (!vrr->supported || !vrr->send_vsif) +	if (!vrr->supported || (!vrr->send_info_frame && packet_type != PACKET_TYPE_VTEM))  		return;  	switch (packet_type) {  	case PACKET_TYPE_FS2:  		build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket);  		break; +	case PACKET_TYPE_VTEM: +		build_vrr_infopacket_vtem(stream, vrr, infopacket); +		break;  	case PACKET_TYPE_VRR:  	case PACKET_TYPE_FS1:  	default: @@ -739,7 +823,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  		return;  	in_out_vrr->state = in_config->state; -	in_out_vrr->send_vsif = in_config->vsif_supported; +	in_out_vrr->send_info_frame = in_config->vsif_supported;  	if (in_config->state == VRR_STATE_UNSUPPORTED) {  		in_out_vrr->state = VRR_STATE_UNSUPPORTED; @@ -972,7 +1056,7 @@ unsigned long long mod_freesync_calc_nominal_field_rate(  	unsigned long long nominal_field_rate_in_uhz = 0;  	/* Calculate nominal field rate for stream */ -	nominal_field_rate_in_uhz = stream->timing.pix_clk_khz; +	nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10;  	nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL;  	nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz,  						stream->timing.h_total); diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h index 949a8b62aa98..4222e403b151 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h @@ -104,7 +104,7 @@ struct mod_vrr_params_fixed_refresh {  struct mod_vrr_params {  	bool supported; -	bool send_vsif; +	bool send_info_frame;  	enum mod_vrr_state state;  	uint32_t min_refresh_in_uhz; diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h b/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h index 1bd02c0ac30c..b711e7e6c204 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h @@ -41,7 +41,8 @@ enum color_transfer_func {  enum vrr_packet_type {  	PACKET_TYPE_VRR,  	PACKET_TYPE_FS1, -	PACKET_TYPE_FS2 +	PACKET_TYPE_FS2, +	PACKET_TYPE_VTEM  }; diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index c11a443dcbc8..038b88221c5f 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -41,6 +41,17 @@ static const unsigned char min_reduction_table[13] = {  static const unsigned char max_reduction_table[13] = {  0xf5, 0xe5, 0xd9, 0xcd, 0xb1, 0xa5, 0xa5, 0x80, 0x65, 0x4d, 0x4d, 0x4d, 0x32}; +/* ABM 2.2 Min Reduction effectively disabled (100% for all configs)*/ +static const unsigned char min_reduction_table_v_2_2[13] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + +/* Possible ABM 2.2 Max Reduction configs from least aggressive to most aggressive + *  0    1     2     3     4     5     6     7     8     9     10    11   12 + * 96.1 89.8 74.9  69.4  64.7  52.2  48.6  39.6  30.2  25.1  19.6  12.5  12.5 % + */ +static const unsigned char max_reduction_table_v_2_2[13] = { +0xf5, 0xe5, 0xbf, 0xb1, 0xa5, 0x85, 0x7c, 0x65, 0x4d, 0x40, 0x32, 0x20, 0x20}; +  /* Predefined ABM configuration sets. We may have different configuration sets   * in order to satisfy different power/quality requirements.   */ @@ -56,6 +67,13 @@ static const unsigned char abm_config[abm_defines_max_config][abm_defines_max_le  #define NUM_AGGR_LEVEL    4  #define NUM_POWER_FN_SEGS 8  #define NUM_BL_CURVE_SEGS 16 +#define IRAM_SIZE 256 + +#define IRAM_RESERVE_AREA_START_V2 0xF0  // reserve 0xF0~0xF6 are write by DMCU only +#define IRAM_RESERVE_AREA_END_V2 0xF6  // reserve 0xF0~0xF6 are write by DMCU only + +#define IRAM_RESERVE_AREA_START_V2_2 0xF0  // reserve 0xF0~0xFF are write by DMCU only +#define IRAM_RESERVE_AREA_END_V2_2 0xFF  // reserve 0xF0~0xFF are write by DMCU only  #pragma pack(push, 1)  /* NOTE: iRAM is 256B in size */ @@ -86,11 +104,10 @@ struct iram_table_v_2 {  	/* For reading PSR State directly from IRAM */  	uint8_t psr_state;						/* 0xf0       */ -	uint8_t dmcu_interface_version;					/* 0xf1       */ -	uint8_t dmcu_date_version_year_b0;				/* 0xf2       */ -	uint8_t dmcu_date_version_year_b1;				/* 0xf3       */ -	uint8_t dmcu_date_version_month;				/* 0xf4       */ -	uint8_t dmcu_date_version_day;					/* 0xf5       */ +	uint8_t dmcu_mcp_interface_version;							/* 0xf1       */ +	uint8_t dmcu_abm_feature_version;							/* 0xf2       */ +	uint8_t dmcu_psr_feature_version;							/* 0xf3       */ +	uint16_t dmcu_version;										/* 0xf4       */  	uint8_t dmcu_state;						/* 0xf6       */  	uint16_t blRampReduction;					/* 0xf7       */ @@ -101,20 +118,58 @@ struct iram_table_v_2 {  	uint8_t dummy8;							/* 0xfe       */  	uint8_t dummy9;							/* 0xff       */  }; -#pragma pack(pop) -static uint16_t backlight_8_to_16(unsigned int backlight_8bit) -{ -	return (uint16_t)(backlight_8bit * 0x101); -} +struct iram_table_v_2_2 { +	/* flags                      */ +	uint16_t flags;							/* 0x00 U16  */ + +	/* parameters for ABM2.2 algorithm */ +	uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];		/* 0x02 U0.8 */ +	uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];		/* 0x16 U0.8 */ +	uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];	/* 0x2a U2.6 */ +	uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];		/* 0x3e U2.6 */ +	uint8_t hybridFactor[NUM_AGGR_LEVEL];						/* 0x52 U0.8 */ +	uint8_t contrastFactor[NUM_AGGR_LEVEL];						/* 0x56 U0.8 */ +	uint8_t deviation_gain[NUM_AGGR_LEVEL];						/* 0x5a U0.8 */ +	uint8_t iir_curve[NUM_AMBI_LEVEL];							/* 0x5e U0.8 */ +	uint8_t pad[29];											/* 0x63 U0.8 */ + +	/* parameters for crgb conversion */ +	uint16_t crgb_thresh[NUM_POWER_FN_SEGS];					/* 0x80 U3.13 */ +	uint16_t crgb_offset[NUM_POWER_FN_SEGS];					/* 0x90 U1.15 */ +	uint16_t crgb_slope[NUM_POWER_FN_SEGS];						/* 0xa0 U4.12 */ + +	/* parameters for custom curve */ +	/* thresholds for brightness --> backlight */ +	uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS];			/* 0xb0 U16.0 */ +	/* offsets for brightness --> backlight */ +	uint16_t backlight_offsets[NUM_BL_CURVE_SEGS];				/* 0xd0 U16.0 */ + +	/* For reading PSR State directly from IRAM */ +	uint8_t psr_state;											/* 0xf0       */ +	uint8_t dmcu_mcp_interface_version;							/* 0xf1       */ +	uint8_t dmcu_abm_feature_version;							/* 0xf2       */ +	uint8_t dmcu_psr_feature_version;							/* 0xf3       */ +	uint16_t dmcu_version;										/* 0xf4       */ +	uint8_t dmcu_state;											/* 0xf6       */ + +	uint8_t dummy1;												/* 0xf7       */ +	uint8_t dummy2;												/* 0xf8       */ +	uint8_t dummy3;												/* 0xf9       */ +	uint8_t dummy4;												/* 0xfa       */ +	uint8_t dummy5;												/* 0xfb       */ +	uint8_t dummy6;												/* 0xfc       */ +	uint8_t dummy7;												/* 0xfd       */ +	uint8_t dummy8;												/* 0xfe       */ +	uint8_t dummy9;												/* 0xff       */ +}; +#pragma pack(pop)  static void fill_backlight_transform_table(struct dmcu_iram_parameters params,  		struct iram_table_v_2 *table)  {  	unsigned int i;  	unsigned int num_entries = NUM_BL_CURVE_SEGS; -	unsigned int query_input_8bit; -	unsigned int query_output_8bit;  	unsigned int lut_index;  	table->backlight_thresholds[0] = 0; @@ -132,24 +187,368 @@ static void fill_backlight_transform_table(struct dmcu_iram_parameters params,  	 * format U4.10.  	 */  	for (i = 1; i+1 < num_entries; i++) { -		query_input_8bit = DIV_ROUNDUP((i * 256), num_entries); +		lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1); +		ASSERT(lut_index < params.backlight_lut_array_size); + +		table->backlight_thresholds[i] = +			cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries)); +		table->backlight_offsets[i] = +			cpu_to_be16(params.backlight_lut_array[lut_index]); +	} +} +static void fill_backlight_transform_table_v_2_2(struct dmcu_iram_parameters params, +		struct iram_table_v_2_2 *table) +{ +	unsigned int i; +	unsigned int num_entries = NUM_BL_CURVE_SEGS; +	unsigned int lut_index; + +	table->backlight_thresholds[0] = 0; +	table->backlight_offsets[0] = params.backlight_lut_array[0]; +	table->backlight_thresholds[num_entries-1] = 0xFFFF; +	table->backlight_offsets[num_entries-1] = +		params.backlight_lut_array[params.backlight_lut_array_size - 1]; + +	/* Setup all brightness levels between 0% and 100% exclusive +	 * Fills brightness-to-backlight transform table. Backlight custom curve +	 * describes transform from brightness to backlight. It will be defined +	 * as set of thresholds and set of offsets, together, implying +	 * extrapolation of custom curve into 16 uniformly spanned linear +	 * segments.  Each threshold/offset represented by 16 bit entry in +	 * format U4.10. +	 */ +	for (i = 1; i+1 < num_entries; i++) {  		lut_index = (params.backlight_lut_array_size - 1) * i / (num_entries - 1);  		ASSERT(lut_index < params.backlight_lut_array_size); -		query_output_8bit = params.backlight_lut_array[lut_index] >> 8;  		table->backlight_thresholds[i] = -				backlight_8_to_16(query_input_8bit); +			cpu_to_be16(DIV_ROUNDUP((i * 65536), num_entries));  		table->backlight_offsets[i] = -				backlight_8_to_16(query_output_8bit); +			cpu_to_be16(params.backlight_lut_array[lut_index]);  	}  } +void fill_iram_v_2(struct iram_table_v_2 *ram_table, struct dmcu_iram_parameters params) +{ +	unsigned int set = params.set; + +	ram_table->flags = 0x0; +	ram_table->deviation_gain = 0xb3; + +	ram_table->blRampReduction = +		cpu_to_be16(params.backlight_ramping_reduction); +	ram_table->blRampStart = +		cpu_to_be16(params.backlight_ramping_start); + +	ram_table->min_reduction[0][0] = min_reduction_table[abm_config[set][0]]; +	ram_table->min_reduction[1][0] = min_reduction_table[abm_config[set][0]]; +	ram_table->min_reduction[2][0] = min_reduction_table[abm_config[set][0]]; +	ram_table->min_reduction[3][0] = min_reduction_table[abm_config[set][0]]; +	ram_table->min_reduction[4][0] = min_reduction_table[abm_config[set][0]]; +	ram_table->max_reduction[0][0] = max_reduction_table[abm_config[set][0]]; +	ram_table->max_reduction[1][0] = max_reduction_table[abm_config[set][0]]; +	ram_table->max_reduction[2][0] = max_reduction_table[abm_config[set][0]]; +	ram_table->max_reduction[3][0] = max_reduction_table[abm_config[set][0]]; +	ram_table->max_reduction[4][0] = max_reduction_table[abm_config[set][0]]; + +	ram_table->min_reduction[0][1] = min_reduction_table[abm_config[set][1]]; +	ram_table->min_reduction[1][1] = min_reduction_table[abm_config[set][1]]; +	ram_table->min_reduction[2][1] = min_reduction_table[abm_config[set][1]]; +	ram_table->min_reduction[3][1] = min_reduction_table[abm_config[set][1]]; +	ram_table->min_reduction[4][1] = min_reduction_table[abm_config[set][1]]; +	ram_table->max_reduction[0][1] = max_reduction_table[abm_config[set][1]]; +	ram_table->max_reduction[1][1] = max_reduction_table[abm_config[set][1]]; +	ram_table->max_reduction[2][1] = max_reduction_table[abm_config[set][1]]; +	ram_table->max_reduction[3][1] = max_reduction_table[abm_config[set][1]]; +	ram_table->max_reduction[4][1] = max_reduction_table[abm_config[set][1]]; + +	ram_table->min_reduction[0][2] = min_reduction_table[abm_config[set][2]]; +	ram_table->min_reduction[1][2] = min_reduction_table[abm_config[set][2]]; +	ram_table->min_reduction[2][2] = min_reduction_table[abm_config[set][2]]; +	ram_table->min_reduction[3][2] = min_reduction_table[abm_config[set][2]]; +	ram_table->min_reduction[4][2] = min_reduction_table[abm_config[set][2]]; +	ram_table->max_reduction[0][2] = max_reduction_table[abm_config[set][2]]; +	ram_table->max_reduction[1][2] = max_reduction_table[abm_config[set][2]]; +	ram_table->max_reduction[2][2] = max_reduction_table[abm_config[set][2]]; +	ram_table->max_reduction[3][2] = max_reduction_table[abm_config[set][2]]; +	ram_table->max_reduction[4][2] = max_reduction_table[abm_config[set][2]]; + +	ram_table->min_reduction[0][3] = min_reduction_table[abm_config[set][3]]; +	ram_table->min_reduction[1][3] = min_reduction_table[abm_config[set][3]]; +	ram_table->min_reduction[2][3] = min_reduction_table[abm_config[set][3]]; +	ram_table->min_reduction[3][3] = min_reduction_table[abm_config[set][3]]; +	ram_table->min_reduction[4][3] = min_reduction_table[abm_config[set][3]]; +	ram_table->max_reduction[0][3] = max_reduction_table[abm_config[set][3]]; +	ram_table->max_reduction[1][3] = max_reduction_table[abm_config[set][3]]; +	ram_table->max_reduction[2][3] = max_reduction_table[abm_config[set][3]]; +	ram_table->max_reduction[3][3] = max_reduction_table[abm_config[set][3]]; +	ram_table->max_reduction[4][3] = max_reduction_table[abm_config[set][3]]; + +	ram_table->bright_pos_gain[0][0] = 0x20; +	ram_table->bright_pos_gain[0][1] = 0x20; +	ram_table->bright_pos_gain[0][2] = 0x20; +	ram_table->bright_pos_gain[0][3] = 0x20; +	ram_table->bright_pos_gain[1][0] = 0x20; +	ram_table->bright_pos_gain[1][1] = 0x20; +	ram_table->bright_pos_gain[1][2] = 0x20; +	ram_table->bright_pos_gain[1][3] = 0x20; +	ram_table->bright_pos_gain[2][0] = 0x20; +	ram_table->bright_pos_gain[2][1] = 0x20; +	ram_table->bright_pos_gain[2][2] = 0x20; +	ram_table->bright_pos_gain[2][3] = 0x20; +	ram_table->bright_pos_gain[3][0] = 0x20; +	ram_table->bright_pos_gain[3][1] = 0x20; +	ram_table->bright_pos_gain[3][2] = 0x20; +	ram_table->bright_pos_gain[3][3] = 0x20; +	ram_table->bright_pos_gain[4][0] = 0x20; +	ram_table->bright_pos_gain[4][1] = 0x20; +	ram_table->bright_pos_gain[4][2] = 0x20; +	ram_table->bright_pos_gain[4][3] = 0x20; +	ram_table->bright_neg_gain[0][1] = 0x00; +	ram_table->bright_neg_gain[0][2] = 0x00; +	ram_table->bright_neg_gain[0][3] = 0x00; +	ram_table->bright_neg_gain[1][0] = 0x00; +	ram_table->bright_neg_gain[1][1] = 0x00; +	ram_table->bright_neg_gain[1][2] = 0x00; +	ram_table->bright_neg_gain[1][3] = 0x00; +	ram_table->bright_neg_gain[2][0] = 0x00; +	ram_table->bright_neg_gain[2][1] = 0x00; +	ram_table->bright_neg_gain[2][2] = 0x00; +	ram_table->bright_neg_gain[2][3] = 0x00; +	ram_table->bright_neg_gain[3][0] = 0x00; +	ram_table->bright_neg_gain[3][1] = 0x00; +	ram_table->bright_neg_gain[3][2] = 0x00; +	ram_table->bright_neg_gain[3][3] = 0x00; +	ram_table->bright_neg_gain[4][0] = 0x00; +	ram_table->bright_neg_gain[4][1] = 0x00; +	ram_table->bright_neg_gain[4][2] = 0x00; +	ram_table->bright_neg_gain[4][3] = 0x00; +	ram_table->dark_pos_gain[0][0] = 0x00; +	ram_table->dark_pos_gain[0][1] = 0x00; +	ram_table->dark_pos_gain[0][2] = 0x00; +	ram_table->dark_pos_gain[0][3] = 0x00; +	ram_table->dark_pos_gain[1][0] = 0x00; +	ram_table->dark_pos_gain[1][1] = 0x00; +	ram_table->dark_pos_gain[1][2] = 0x00; +	ram_table->dark_pos_gain[1][3] = 0x00; +	ram_table->dark_pos_gain[2][0] = 0x00; +	ram_table->dark_pos_gain[2][1] = 0x00; +	ram_table->dark_pos_gain[2][2] = 0x00; +	ram_table->dark_pos_gain[2][3] = 0x00; +	ram_table->dark_pos_gain[3][0] = 0x00; +	ram_table->dark_pos_gain[3][1] = 0x00; +	ram_table->dark_pos_gain[3][2] = 0x00; +	ram_table->dark_pos_gain[3][3] = 0x00; +	ram_table->dark_pos_gain[4][0] = 0x00; +	ram_table->dark_pos_gain[4][1] = 0x00; +	ram_table->dark_pos_gain[4][2] = 0x00; +	ram_table->dark_pos_gain[4][3] = 0x00; +	ram_table->dark_neg_gain[0][0] = 0x00; +	ram_table->dark_neg_gain[0][1] = 0x00; +	ram_table->dark_neg_gain[0][2] = 0x00; +	ram_table->dark_neg_gain[0][3] = 0x00; +	ram_table->dark_neg_gain[1][0] = 0x00; +	ram_table->dark_neg_gain[1][1] = 0x00; +	ram_table->dark_neg_gain[1][2] = 0x00; +	ram_table->dark_neg_gain[1][3] = 0x00; +	ram_table->dark_neg_gain[2][0] = 0x00; +	ram_table->dark_neg_gain[2][1] = 0x00; +	ram_table->dark_neg_gain[2][2] = 0x00; +	ram_table->dark_neg_gain[2][3] = 0x00; +	ram_table->dark_neg_gain[3][0] = 0x00; +	ram_table->dark_neg_gain[3][1] = 0x00; +	ram_table->dark_neg_gain[3][2] = 0x00; +	ram_table->dark_neg_gain[3][3] = 0x00; +	ram_table->dark_neg_gain[4][0] = 0x00; +	ram_table->dark_neg_gain[4][1] = 0x00; +	ram_table->dark_neg_gain[4][2] = 0x00; +	ram_table->dark_neg_gain[4][3] = 0x00; + +	ram_table->iir_curve[0] = 0x65; +	ram_table->iir_curve[1] = 0x65; +	ram_table->iir_curve[2] = 0x65; +	ram_table->iir_curve[3] = 0x65; +	ram_table->iir_curve[4] = 0x65; + +	//Gamma 2.4 +	ram_table->crgb_thresh[0] = cpu_to_be16(0x13b6); +	ram_table->crgb_thresh[1] = cpu_to_be16(0x1648); +	ram_table->crgb_thresh[2] = cpu_to_be16(0x18e3); +	ram_table->crgb_thresh[3] = cpu_to_be16(0x1b41); +	ram_table->crgb_thresh[4] = cpu_to_be16(0x1d46); +	ram_table->crgb_thresh[5] = cpu_to_be16(0x1f21); +	ram_table->crgb_thresh[6] = cpu_to_be16(0x2167); +	ram_table->crgb_thresh[7] = cpu_to_be16(0x2384); +	ram_table->crgb_offset[0] = cpu_to_be16(0x2999); +	ram_table->crgb_offset[1] = cpu_to_be16(0x3999); +	ram_table->crgb_offset[2] = cpu_to_be16(0x4666); +	ram_table->crgb_offset[3] = cpu_to_be16(0x5999); +	ram_table->crgb_offset[4] = cpu_to_be16(0x6333); +	ram_table->crgb_offset[5] = cpu_to_be16(0x7800); +	ram_table->crgb_offset[6] = cpu_to_be16(0x8c00); +	ram_table->crgb_offset[7] = cpu_to_be16(0xa000); +	ram_table->crgb_slope[0]  = cpu_to_be16(0x3147); +	ram_table->crgb_slope[1]  = cpu_to_be16(0x2978); +	ram_table->crgb_slope[2]  = cpu_to_be16(0x23a2); +	ram_table->crgb_slope[3]  = cpu_to_be16(0x1f55); +	ram_table->crgb_slope[4]  = cpu_to_be16(0x1c63); +	ram_table->crgb_slope[5]  = cpu_to_be16(0x1a0f); +	ram_table->crgb_slope[6]  = cpu_to_be16(0x178d); +	ram_table->crgb_slope[7]  = cpu_to_be16(0x15ab); + +	fill_backlight_transform_table( +			params, ram_table); +} + +void fill_iram_v_2_2(struct iram_table_v_2_2 *ram_table, struct dmcu_iram_parameters params) +{ +	unsigned int set = params.set; + +	ram_table->flags = 0x0; + +	ram_table->deviation_gain[0] = 0xb3; +	ram_table->deviation_gain[1] = 0xb3; +	ram_table->deviation_gain[2] = 0xb3; +	ram_table->deviation_gain[3] = 0xb3; + +	ram_table->min_reduction[0][0] = min_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->min_reduction[1][0] = min_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->min_reduction[2][0] = min_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->min_reduction[3][0] = min_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->min_reduction[4][0] = min_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->max_reduction[0][0] = max_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->max_reduction[1][0] = max_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->max_reduction[2][0] = max_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->max_reduction[3][0] = max_reduction_table_v_2_2[abm_config[set][0]]; +	ram_table->max_reduction[4][0] = max_reduction_table_v_2_2[abm_config[set][0]]; + +	ram_table->min_reduction[0][1] = min_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->min_reduction[1][1] = min_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->min_reduction[2][1] = min_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->min_reduction[3][1] = min_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->min_reduction[4][1] = min_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->max_reduction[0][1] = max_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->max_reduction[1][1] = max_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->max_reduction[2][1] = max_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->max_reduction[3][1] = max_reduction_table_v_2_2[abm_config[set][1]]; +	ram_table->max_reduction[4][1] = max_reduction_table_v_2_2[abm_config[set][1]]; + +	ram_table->min_reduction[0][2] = min_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->min_reduction[1][2] = min_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->min_reduction[2][2] = min_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->min_reduction[3][2] = min_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->min_reduction[4][2] = min_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->max_reduction[0][2] = max_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->max_reduction[1][2] = max_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->max_reduction[2][2] = max_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->max_reduction[3][2] = max_reduction_table_v_2_2[abm_config[set][2]]; +	ram_table->max_reduction[4][2] = max_reduction_table_v_2_2[abm_config[set][2]]; + +	ram_table->min_reduction[0][3] = min_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->min_reduction[1][3] = min_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->min_reduction[2][3] = min_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->min_reduction[3][3] = min_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->min_reduction[4][3] = min_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->max_reduction[0][3] = max_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->max_reduction[1][3] = max_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->max_reduction[2][3] = max_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->max_reduction[3][3] = max_reduction_table_v_2_2[abm_config[set][3]]; +	ram_table->max_reduction[4][3] = max_reduction_table_v_2_2[abm_config[set][3]]; + +	ram_table->bright_pos_gain[0][0] = 0x20; +	ram_table->bright_pos_gain[0][1] = 0x20; +	ram_table->bright_pos_gain[0][2] = 0x20; +	ram_table->bright_pos_gain[0][3] = 0x20; +	ram_table->bright_pos_gain[1][0] = 0x20; +	ram_table->bright_pos_gain[1][1] = 0x20; +	ram_table->bright_pos_gain[1][2] = 0x20; +	ram_table->bright_pos_gain[1][3] = 0x20; +	ram_table->bright_pos_gain[2][0] = 0x20; +	ram_table->bright_pos_gain[2][1] = 0x20; +	ram_table->bright_pos_gain[2][2] = 0x20; +	ram_table->bright_pos_gain[2][3] = 0x20; +	ram_table->bright_pos_gain[3][0] = 0x20; +	ram_table->bright_pos_gain[3][1] = 0x20; +	ram_table->bright_pos_gain[3][2] = 0x20; +	ram_table->bright_pos_gain[3][3] = 0x20; +	ram_table->bright_pos_gain[4][0] = 0x20; +	ram_table->bright_pos_gain[4][1] = 0x20; +	ram_table->bright_pos_gain[4][2] = 0x20; +	ram_table->bright_pos_gain[4][3] = 0x20; + +	ram_table->dark_pos_gain[0][0] = 0x00; +	ram_table->dark_pos_gain[0][1] = 0x00; +	ram_table->dark_pos_gain[0][2] = 0x00; +	ram_table->dark_pos_gain[0][3] = 0x00; +	ram_table->dark_pos_gain[1][0] = 0x00; +	ram_table->dark_pos_gain[1][1] = 0x00; +	ram_table->dark_pos_gain[1][2] = 0x00; +	ram_table->dark_pos_gain[1][3] = 0x00; +	ram_table->dark_pos_gain[2][0] = 0x00; +	ram_table->dark_pos_gain[2][1] = 0x00; +	ram_table->dark_pos_gain[2][2] = 0x00; +	ram_table->dark_pos_gain[2][3] = 0x00; +	ram_table->dark_pos_gain[3][0] = 0x00; +	ram_table->dark_pos_gain[3][1] = 0x00; +	ram_table->dark_pos_gain[3][2] = 0x00; +	ram_table->dark_pos_gain[3][3] = 0x00; +	ram_table->dark_pos_gain[4][0] = 0x00; +	ram_table->dark_pos_gain[4][1] = 0x00; +	ram_table->dark_pos_gain[4][2] = 0x00; +	ram_table->dark_pos_gain[4][3] = 0x00; + +	ram_table->hybridFactor[0] = 0xff; +	ram_table->hybridFactor[1] = 0xff; +	ram_table->hybridFactor[2] = 0xff; +	ram_table->hybridFactor[3] = 0xc0; + +	ram_table->contrastFactor[0] = 0x99; +	ram_table->contrastFactor[1] = 0x99; +	ram_table->contrastFactor[2] = 0x99; +	ram_table->contrastFactor[3] = 0x80; + +	ram_table->iir_curve[0] = 0x65; +	ram_table->iir_curve[1] = 0x65; +	ram_table->iir_curve[2] = 0x65; +	ram_table->iir_curve[3] = 0x65; +	ram_table->iir_curve[4] = 0x65; + +	//Gamma 2.2 +	ram_table->crgb_thresh[0] = cpu_to_be16(0x127c); +	ram_table->crgb_thresh[1] = cpu_to_be16(0x151b); +	ram_table->crgb_thresh[2] = cpu_to_be16(0x17d5); +	ram_table->crgb_thresh[3] = cpu_to_be16(0x1a56); +	ram_table->crgb_thresh[4] = cpu_to_be16(0x1c83); +	ram_table->crgb_thresh[5] = cpu_to_be16(0x1e72); +	ram_table->crgb_thresh[6] = cpu_to_be16(0x20f0); +	ram_table->crgb_thresh[7] = cpu_to_be16(0x232b); +	ram_table->crgb_offset[0] = cpu_to_be16(0x2999); +	ram_table->crgb_offset[1] = cpu_to_be16(0x3999); +	ram_table->crgb_offset[2] = cpu_to_be16(0x4666); +	ram_table->crgb_offset[3] = cpu_to_be16(0x5999); +	ram_table->crgb_offset[4] = cpu_to_be16(0x6333); +	ram_table->crgb_offset[5] = cpu_to_be16(0x7800); +	ram_table->crgb_offset[6] = cpu_to_be16(0x8c00); +	ram_table->crgb_offset[7] = cpu_to_be16(0xa000); +	ram_table->crgb_slope[0]  = cpu_to_be16(0x3609); +	ram_table->crgb_slope[1]  = cpu_to_be16(0x2dfa); +	ram_table->crgb_slope[2]  = cpu_to_be16(0x27ea); +	ram_table->crgb_slope[3]  = cpu_to_be16(0x235d); +	ram_table->crgb_slope[4]  = cpu_to_be16(0x2042); +	ram_table->crgb_slope[5]  = cpu_to_be16(0x1dc3); +	ram_table->crgb_slope[6]  = cpu_to_be16(0x1b1a); +	ram_table->crgb_slope[7]  = cpu_to_be16(0x1910); + +	fill_backlight_transform_table_v_2_2( +			params, ram_table); +} +  bool dmcu_load_iram(struct dmcu *dmcu,  	struct dmcu_iram_parameters params)  { -	struct iram_table_v_2 ram_table; -	unsigned int set = params.set; +	unsigned char ram_table[IRAM_SIZE]; +	bool result = false;  	if (dmcu == NULL)  		return false; @@ -159,170 +558,23 @@ bool dmcu_load_iram(struct dmcu *dmcu,  	memset(&ram_table, 0, sizeof(ram_table)); -	ram_table.flags = 0x0; -	ram_table.deviation_gain = 0xb3; +	if (dmcu->dmcu_version.abm_version == 0x22) { +		fill_iram_v_2_2((struct iram_table_v_2_2 *)ram_table, params); -	ram_table.blRampReduction = -		cpu_to_be16(params.backlight_ramping_reduction); -	ram_table.blRampStart = -		cpu_to_be16(params.backlight_ramping_start); +		result = dmcu->funcs->load_iram( +				dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2_2); +	} else { +		fill_iram_v_2((struct iram_table_v_2 *)ram_table, params); -	ram_table.min_reduction[0][0] = min_reduction_table[abm_config[set][0]]; -	ram_table.min_reduction[1][0] = min_reduction_table[abm_config[set][0]]; -	ram_table.min_reduction[2][0] = min_reduction_table[abm_config[set][0]]; -	ram_table.min_reduction[3][0] = min_reduction_table[abm_config[set][0]]; -	ram_table.min_reduction[4][0] = min_reduction_table[abm_config[set][0]]; -	ram_table.max_reduction[0][0] = max_reduction_table[abm_config[set][0]]; -	ram_table.max_reduction[1][0] = max_reduction_table[abm_config[set][0]]; -	ram_table.max_reduction[2][0] = max_reduction_table[abm_config[set][0]]; -	ram_table.max_reduction[3][0] = max_reduction_table[abm_config[set][0]]; -	ram_table.max_reduction[4][0] = max_reduction_table[abm_config[set][0]]; - -	ram_table.min_reduction[0][1] = min_reduction_table[abm_config[set][1]]; -	ram_table.min_reduction[1][1] = min_reduction_table[abm_config[set][1]]; -	ram_table.min_reduction[2][1] = min_reduction_table[abm_config[set][1]]; -	ram_table.min_reduction[3][1] = min_reduction_table[abm_config[set][1]]; -	ram_table.min_reduction[4][1] = min_reduction_table[abm_config[set][1]]; -	ram_table.max_reduction[0][1] = max_reduction_table[abm_config[set][1]]; -	ram_table.max_reduction[1][1] = max_reduction_table[abm_config[set][1]]; -	ram_table.max_reduction[2][1] = max_reduction_table[abm_config[set][1]]; -	ram_table.max_reduction[3][1] = max_reduction_table[abm_config[set][1]]; -	ram_table.max_reduction[4][1] = max_reduction_table[abm_config[set][1]]; - -	ram_table.min_reduction[0][2] = min_reduction_table[abm_config[set][2]]; -	ram_table.min_reduction[1][2] = min_reduction_table[abm_config[set][2]]; -	ram_table.min_reduction[2][2] = min_reduction_table[abm_config[set][2]]; -	ram_table.min_reduction[3][2] = min_reduction_table[abm_config[set][2]]; -	ram_table.min_reduction[4][2] = min_reduction_table[abm_config[set][2]]; -	ram_table.max_reduction[0][2] = max_reduction_table[abm_config[set][2]]; -	ram_table.max_reduction[1][2] = max_reduction_table[abm_config[set][2]]; -	ram_table.max_reduction[2][2] = max_reduction_table[abm_config[set][2]]; -	ram_table.max_reduction[3][2] = max_reduction_table[abm_config[set][2]]; -	ram_table.max_reduction[4][2] = max_reduction_table[abm_config[set][2]]; - -	ram_table.min_reduction[0][3] = min_reduction_table[abm_config[set][3]]; -	ram_table.min_reduction[1][3] = min_reduction_table[abm_config[set][3]]; -	ram_table.min_reduction[2][3] = min_reduction_table[abm_config[set][3]]; -	ram_table.min_reduction[3][3] = min_reduction_table[abm_config[set][3]]; -	ram_table.min_reduction[4][3] = min_reduction_table[abm_config[set][3]]; -	ram_table.max_reduction[0][3] = max_reduction_table[abm_config[set][3]]; -	ram_table.max_reduction[1][3] = max_reduction_table[abm_config[set][3]]; -	ram_table.max_reduction[2][3] = max_reduction_table[abm_config[set][3]]; -	ram_table.max_reduction[3][3] = max_reduction_table[abm_config[set][3]]; -	ram_table.max_reduction[4][3] = max_reduction_table[abm_config[set][3]]; - -	ram_table.bright_pos_gain[0][0] = 0x20; -	ram_table.bright_pos_gain[0][1] = 0x20; -	ram_table.bright_pos_gain[0][2] = 0x20; -	ram_table.bright_pos_gain[0][3] = 0x20; -	ram_table.bright_pos_gain[1][0] = 0x20; -	ram_table.bright_pos_gain[1][1] = 0x20; -	ram_table.bright_pos_gain[1][2] = 0x20; -	ram_table.bright_pos_gain[1][3] = 0x20; -	ram_table.bright_pos_gain[2][0] = 0x20; -	ram_table.bright_pos_gain[2][1] = 0x20; -	ram_table.bright_pos_gain[2][2] = 0x20; -	ram_table.bright_pos_gain[2][3] = 0x20; -	ram_table.bright_pos_gain[3][0] = 0x20; -	ram_table.bright_pos_gain[3][1] = 0x20; -	ram_table.bright_pos_gain[3][2] = 0x20; -	ram_table.bright_pos_gain[3][3] = 0x20; -	ram_table.bright_pos_gain[4][0] = 0x20; -	ram_table.bright_pos_gain[4][1] = 0x20; -	ram_table.bright_pos_gain[4][2] = 0x20; -	ram_table.bright_pos_gain[4][3] = 0x20; -	ram_table.bright_neg_gain[0][1] = 0x00; -	ram_table.bright_neg_gain[0][2] = 0x00; -	ram_table.bright_neg_gain[0][3] = 0x00; -	ram_table.bright_neg_gain[1][0] = 0x00; -	ram_table.bright_neg_gain[1][1] = 0x00; -	ram_table.bright_neg_gain[1][2] = 0x00; -	ram_table.bright_neg_gain[1][3] = 0x00; -	ram_table.bright_neg_gain[2][0] = 0x00; -	ram_table.bright_neg_gain[2][1] = 0x00; -	ram_table.bright_neg_gain[2][2] = 0x00; -	ram_table.bright_neg_gain[2][3] = 0x00; -	ram_table.bright_neg_gain[3][0] = 0x00; -	ram_table.bright_neg_gain[3][1] = 0x00; -	ram_table.bright_neg_gain[3][2] = 0x00; -	ram_table.bright_neg_gain[3][3] = 0x00; -	ram_table.bright_neg_gain[4][0] = 0x00; -	ram_table.bright_neg_gain[4][1] = 0x00; -	ram_table.bright_neg_gain[4][2] = 0x00; -	ram_table.bright_neg_gain[4][3] = 0x00; -	ram_table.dark_pos_gain[0][0] = 0x00; -	ram_table.dark_pos_gain[0][1] = 0x00; -	ram_table.dark_pos_gain[0][2] = 0x00; -	ram_table.dark_pos_gain[0][3] = 0x00; -	ram_table.dark_pos_gain[1][0] = 0x00; -	ram_table.dark_pos_gain[1][1] = 0x00; -	ram_table.dark_pos_gain[1][2] = 0x00; -	ram_table.dark_pos_gain[1][3] = 0x00; -	ram_table.dark_pos_gain[2][0] = 0x00; -	ram_table.dark_pos_gain[2][1] = 0x00; -	ram_table.dark_pos_gain[2][2] = 0x00; -	ram_table.dark_pos_gain[2][3] = 0x00; -	ram_table.dark_pos_gain[3][0] = 0x00; -	ram_table.dark_pos_gain[3][1] = 0x00; -	ram_table.dark_pos_gain[3][2] = 0x00; -	ram_table.dark_pos_gain[3][3] = 0x00; -	ram_table.dark_pos_gain[4][0] = 0x00; -	ram_table.dark_pos_gain[4][1] = 0x00; -	ram_table.dark_pos_gain[4][2] = 0x00; -	ram_table.dark_pos_gain[4][3] = 0x00; -	ram_table.dark_neg_gain[0][0] = 0x00; -	ram_table.dark_neg_gain[0][1] = 0x00; -	ram_table.dark_neg_gain[0][2] = 0x00; -	ram_table.dark_neg_gain[0][3] = 0x00; -	ram_table.dark_neg_gain[1][0] = 0x00; -	ram_table.dark_neg_gain[1][1] = 0x00; -	ram_table.dark_neg_gain[1][2] = 0x00; -	ram_table.dark_neg_gain[1][3] = 0x00; -	ram_table.dark_neg_gain[2][0] = 0x00; -	ram_table.dark_neg_gain[2][1] = 0x00; -	ram_table.dark_neg_gain[2][2] = 0x00; -	ram_table.dark_neg_gain[2][3] = 0x00; -	ram_table.dark_neg_gain[3][0] = 0x00; -	ram_table.dark_neg_gain[3][1] = 0x00; -	ram_table.dark_neg_gain[3][2] = 0x00; -	ram_table.dark_neg_gain[3][3] = 0x00; -	ram_table.dark_neg_gain[4][0] = 0x00; -	ram_table.dark_neg_gain[4][1] = 0x00; -	ram_table.dark_neg_gain[4][2] = 0x00; -	ram_table.dark_neg_gain[4][3] = 0x00; -	ram_table.iir_curve[0] = 0x65; -	ram_table.iir_curve[1] = 0x65; -	ram_table.iir_curve[2] = 0x65; -	ram_table.iir_curve[3] = 0x65; -	ram_table.iir_curve[4] = 0x65; -	ram_table.crgb_thresh[0] = cpu_to_be16(0x13b6); -	ram_table.crgb_thresh[1] = cpu_to_be16(0x1648); -	ram_table.crgb_thresh[2] = cpu_to_be16(0x18e3); -	ram_table.crgb_thresh[3] = cpu_to_be16(0x1b41); -	ram_table.crgb_thresh[4] = cpu_to_be16(0x1d46); -	ram_table.crgb_thresh[5] = cpu_to_be16(0x1f21); -	ram_table.crgb_thresh[6] = cpu_to_be16(0x2167); -	ram_table.crgb_thresh[7] = cpu_to_be16(0x2384); -	ram_table.crgb_offset[0] = cpu_to_be16(0x2999); -	ram_table.crgb_offset[1] = cpu_to_be16(0x3999); -	ram_table.crgb_offset[2] = cpu_to_be16(0x4666); -	ram_table.crgb_offset[3] = cpu_to_be16(0x5999); -	ram_table.crgb_offset[4] = cpu_to_be16(0x6333); -	ram_table.crgb_offset[5] = cpu_to_be16(0x7800); -	ram_table.crgb_offset[6] = cpu_to_be16(0x8c00); -	ram_table.crgb_offset[7] = cpu_to_be16(0xa000); -	ram_table.crgb_slope[0]  = cpu_to_be16(0x3147); -	ram_table.crgb_slope[1]  = cpu_to_be16(0x2978); -	ram_table.crgb_slope[2]  = cpu_to_be16(0x23a2); -	ram_table.crgb_slope[3]  = cpu_to_be16(0x1f55); -	ram_table.crgb_slope[4]  = cpu_to_be16(0x1c63); -	ram_table.crgb_slope[5]  = cpu_to_be16(0x1a0f); -	ram_table.crgb_slope[6]  = cpu_to_be16(0x178d); -	ram_table.crgb_slope[7]  = cpu_to_be16(0x15ab); +		result = dmcu->funcs->load_iram( +				dmcu, 0, (char *)(&ram_table), IRAM_RESERVE_AREA_START_V2); -	fill_backlight_transform_table( -			params, &ram_table); +		if (result) +			result = dmcu->funcs->load_iram( +					dmcu, IRAM_RESERVE_AREA_END_V2 + 1, +					(char *)(&ram_table) + IRAM_RESERVE_AREA_END_V2 + 1, +					sizeof(ram_table) - IRAM_RESERVE_AREA_END_V2 - 1); +	} -	return dmcu->funcs->load_iram( -			dmcu, 0, (char *)(&ram_table), sizeof(ram_table)); +	return result;  } | 
