diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/freesync')
| -rw-r--r-- | drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 78 | 
1 files changed, 50 insertions, 28 deletions
| diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index eb7421e83b86..7a2500fbf3f2 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -32,7 +32,7 @@  #define MOD_FREESYNC_MAX_CONCURRENT_STREAMS  32 -#define MIN_REFRESH_RANGE_IN_US 10000000 +#define MIN_REFRESH_RANGE 10  /* Refresh rate ramp at a fixed rate of 65 Hz/second */  #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65)  /* Number of elements in the render times cache array */ @@ -760,9 +760,35 @@ static void build_vrr_infopacket_v2(enum signal_type signal,  	infopacket->valid = true;  } +#ifndef TRIM_FSFT +static void build_vrr_infopacket_fast_transport_data( +	bool ftActive, +	unsigned int ftOutputRate, +	struct dc_info_packet *infopacket) +{ +	/* PB9 : bit7 - fast transport Active*/ +	unsigned char activeBit = (ftActive) ? 1 << 7 : 0; + +	infopacket->sb[1] &= ~activeBit;  //clear bit +	infopacket->sb[1] |=  activeBit;  //set bit + +	/* PB13 : Target Output Pixel Rate [kHz] - bits 7:0  */ +	infopacket->sb[13] = ftOutputRate & 0xFF; + +	/* PB14 : Target Output Pixel Rate [kHz] - bits 15:8  */ +	infopacket->sb[14] = (ftOutputRate >> 8) & 0xFF; + +	/* PB15 : Target Output Pixel Rate [kHz] - bits 23:16  */ +	infopacket->sb[15] = (ftOutputRate >> 16) & 0xFF; + +} +#endif  static void build_vrr_infopacket_v3(enum signal_type signal,  		const struct mod_vrr_params *vrr, +#ifndef TRIM_FSFT +		bool ftActive, unsigned int ftOutputRate, +#endif  		enum color_transfer_func app_tf,  		struct dc_info_packet *infopacket)  { @@ -773,6 +799,13 @@ static void build_vrr_infopacket_v3(enum signal_type signal,  	build_vrr_infopacket_fs2_data(app_tf, infopacket); +#ifndef TRIM_FSFT +	build_vrr_infopacket_fast_transport_data( +			ftActive, +			ftOutputRate, +			infopacket); +#endif +  	build_vrr_infopacket_checksum(&payload_size, infopacket);  	infopacket->valid = true; @@ -790,12 +823,20 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,  	 * Check if Freesync is supported. Return if false. If true,  	 * set the corresponding bit in the info packet  	 */ -	if (!vrr->supported || (!vrr->send_info_frame)) +	if (!vrr->send_info_frame)  		return;  	switch (packet_type) {  	case PACKET_TYPE_FS_V3: +#ifndef TRIM_FSFT +		build_vrr_infopacket_v3( +				stream->signal, vrr, +				stream->timing.flags.FAST_TRANSPORT, +				stream->timing.fast_transport_output_rate_100hz, +				app_tf, infopacket); +#else  		build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket); +#endif  		break;  	case PACKET_TYPE_FS_V2:  		build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket); @@ -878,8 +919,8 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  		else  			in_out_vrr->fixed_refresh_in_uhz = 0; -		refresh_range = in_out_vrr->max_refresh_in_uhz - -				in_out_vrr->min_refresh_in_uhz; +		refresh_range = div_u64(in_out_vrr->max_refresh_in_uhz + 500000, 1000000) - ++				div_u64(in_out_vrr->min_refresh_in_uhz + 500000, 1000000);  		in_out_vrr->supported = true;  	} @@ -918,7 +959,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,  		in_out_vrr->adjust.v_total_min = stream->timing.v_total;  		in_out_vrr->adjust.v_total_max = stream->timing.v_total;  	} else if (in_out_vrr->state == VRR_STATE_ACTIVE_VARIABLE && -			refresh_range >= MIN_REFRESH_RANGE_IN_US) { +			refresh_range >= MIN_REFRESH_RANGE) {  		in_out_vrr->adjust.v_total_min =  			calc_v_total_from_refresh(stream, @@ -1105,16 +1146,10 @@ unsigned long long mod_freesync_calc_nominal_field_rate(  	return nominal_field_rate_in_uhz;  } -bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync, -		const struct dc_stream_state *stream, -		uint32_t min_refresh_cap_in_uhz, +bool mod_freesync_is_valid_range(uint32_t min_refresh_cap_in_uhz,  		uint32_t max_refresh_cap_in_uhz, -		uint32_t min_refresh_request_in_uhz, -		uint32_t max_refresh_request_in_uhz) +		uint32_t nominal_field_rate_in_uhz)   { -	/* Calculate nominal field rate for stream */ -	unsigned long long nominal_field_rate_in_uhz = -			mod_freesync_calc_nominal_field_rate(stream);  	/* Typically nominal refresh calculated can have some fractional part.  	 * Allow for some rounding error of actual video timing by taking floor @@ -1153,8 +1188,6 @@ bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync,  			div_u64(nominal_field_rate_in_uhz + 500000, 1000000);  	min_refresh_cap_in_uhz /= 1000000;  	max_refresh_cap_in_uhz /= 1000000; -	min_refresh_request_in_uhz /= 1000000; -	max_refresh_request_in_uhz /= 1000000;  	// Check nominal is within range  	if (nominal_field_rate_in_uhz > max_refresh_cap_in_uhz || @@ -1165,23 +1198,12 @@ bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync,  	if (nominal_field_rate_in_uhz < max_refresh_cap_in_uhz)  		max_refresh_cap_in_uhz = nominal_field_rate_in_uhz; -	// Don't allow min > max -	if (min_refresh_request_in_uhz > max_refresh_request_in_uhz) -		return false; -  	// Check min is within range -	if (min_refresh_request_in_uhz > max_refresh_cap_in_uhz || -		min_refresh_request_in_uhz < min_refresh_cap_in_uhz) -		return false; - -	// Check max is within range -	if (max_refresh_request_in_uhz > max_refresh_cap_in_uhz || -		max_refresh_request_in_uhz < min_refresh_cap_in_uhz) +	if (min_refresh_cap_in_uhz > max_refresh_cap_in_uhz)  		return false;  	// For variable range, check for at least 10 Hz range -	if ((max_refresh_request_in_uhz != min_refresh_request_in_uhz) && -		(max_refresh_request_in_uhz - min_refresh_request_in_uhz < 10)) +	if (nominal_field_rate_in_uhz - min_refresh_cap_in_uhz < 10)  		return false;  	return true; | 
