diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/dce_v8_0.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 431 | 
1 files changed, 207 insertions, 224 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 4fdfab1e9200..584abe834a3c 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -31,6 +31,7 @@  #include "atombios_encoders.h"  #include "amdgpu_pll.h"  #include "amdgpu_connectors.h" +#include "dce_v8_0.h"  #include "dce/dce_8_0_d.h"  #include "dce/dce_8_0_sh_mask.h" @@ -56,6 +57,16 @@ static const u32 crtc_offsets[6] =  	CRTC5_REGISTER_OFFSET  }; +static const u32 hpd_offsets[] = +{ +	HPD0_REGISTER_OFFSET, +	HPD1_REGISTER_OFFSET, +	HPD2_REGISTER_OFFSET, +	HPD3_REGISTER_OFFSET, +	HPD4_REGISTER_OFFSET, +	HPD5_REGISTER_OFFSET +}; +  static const uint32_t dig_offsets[] = {  	CRTC0_REGISTER_OFFSET,  	CRTC1_REGISTER_OFFSET, @@ -104,15 +115,6 @@ static const struct {  	.hpd = DISP_INTERRUPT_STATUS_CONTINUE5__DC_HPD6_INTERRUPT_MASK  } }; -static const uint32_t hpd_int_control_offsets[6] = { -	mmDC_HPD1_INT_CONTROL, -	mmDC_HPD2_INT_CONTROL, -	mmDC_HPD3_INT_CONTROL, -	mmDC_HPD4_INT_CONTROL, -	mmDC_HPD5_INT_CONTROL, -	mmDC_HPD6_INT_CONTROL, -}; -  static u32 dce_v8_0_audio_endpt_rreg(struct amdgpu_device *adev,  				     u32 block_offset, u32 reg)  { @@ -170,7 +172,7 @@ static bool dce_v8_0_is_counter_moving(struct amdgpu_device *adev, int crtc)   */  static void dce_v8_0_vblank_wait(struct amdgpu_device *adev, int crtc)  { -	unsigned i = 0; +	unsigned i = 100;  	if (crtc >= adev->mode_info.num_crtc)  		return; @@ -182,14 +184,16 @@ static void dce_v8_0_vblank_wait(struct amdgpu_device *adev, int crtc)  	 * wait for another frame.  	 */  	while (dce_v8_0_is_in_vblank(adev, crtc)) { -		if (i++ % 100 == 0) { +		if (i++ == 100) { +			i = 0;  			if (!dce_v8_0_is_counter_moving(adev, crtc))  				break;  		}  	}  	while (!dce_v8_0_is_in_vblank(adev, crtc)) { -		if (i++ % 100 == 0) { +		if (i++ == 100) { +			i = 0;  			if (!dce_v8_0_is_counter_moving(adev, crtc))  				break;  		} @@ -276,34 +280,12 @@ static bool dce_v8_0_hpd_sense(struct amdgpu_device *adev,  {  	bool connected = false; -	switch (hpd) { -	case AMDGPU_HPD_1: -		if (RREG32(mmDC_HPD1_INT_STATUS) & DC_HPD1_INT_STATUS__DC_HPD1_SENSE_MASK) -			connected = true; -		break; -	case AMDGPU_HPD_2: -		if (RREG32(mmDC_HPD2_INT_STATUS) & DC_HPD2_INT_STATUS__DC_HPD2_SENSE_MASK) -			connected = true; -		break; -	case AMDGPU_HPD_3: -		if (RREG32(mmDC_HPD3_INT_STATUS) & DC_HPD3_INT_STATUS__DC_HPD3_SENSE_MASK) -			connected = true; -		break; -	case AMDGPU_HPD_4: -		if (RREG32(mmDC_HPD4_INT_STATUS) & DC_HPD4_INT_STATUS__DC_HPD4_SENSE_MASK) -			connected = true; -		break; -	case AMDGPU_HPD_5: -		if (RREG32(mmDC_HPD5_INT_STATUS) & DC_HPD5_INT_STATUS__DC_HPD5_SENSE_MASK) -			connected = true; -		break; -	case AMDGPU_HPD_6: -		if (RREG32(mmDC_HPD6_INT_STATUS) & DC_HPD6_INT_STATUS__DC_HPD6_SENSE_MASK) -			connected = true; -		break; -	default: -		break; -	} +	if (hpd >= adev->mode_info.num_hpd) +		return connected; + +	if (RREG32(mmDC_HPD1_INT_STATUS + hpd_offsets[hpd]) & +	    DC_HPD1_INT_STATUS__DC_HPD1_SENSE_MASK) +		connected = true;  	return connected;  } @@ -322,58 +304,15 @@ static void dce_v8_0_hpd_set_polarity(struct amdgpu_device *adev,  	u32 tmp;  	bool connected = dce_v8_0_hpd_sense(adev, hpd); -	switch (hpd) { -	case AMDGPU_HPD_1: -		tmp = RREG32(mmDC_HPD1_INT_CONTROL); -		if (connected) -			tmp &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_POLARITY_MASK; -		else -			tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_POLARITY_MASK; -		WREG32(mmDC_HPD1_INT_CONTROL, tmp); -		break; -	case AMDGPU_HPD_2: -		tmp = RREG32(mmDC_HPD2_INT_CONTROL); -		if (connected) -			tmp &= ~DC_HPD2_INT_CONTROL__DC_HPD2_INT_POLARITY_MASK; -		else -			tmp |= DC_HPD2_INT_CONTROL__DC_HPD2_INT_POLARITY_MASK; -		WREG32(mmDC_HPD2_INT_CONTROL, tmp); -		break; -	case AMDGPU_HPD_3: -		tmp = RREG32(mmDC_HPD3_INT_CONTROL); -		if (connected) -			tmp &= ~DC_HPD3_INT_CONTROL__DC_HPD3_INT_POLARITY_MASK; -		else -			tmp |= DC_HPD3_INT_CONTROL__DC_HPD3_INT_POLARITY_MASK; -		WREG32(mmDC_HPD3_INT_CONTROL, tmp); -		break; -	case AMDGPU_HPD_4: -		tmp = RREG32(mmDC_HPD4_INT_CONTROL); -		if (connected) -			tmp &= ~DC_HPD4_INT_CONTROL__DC_HPD4_INT_POLARITY_MASK; -		else -			tmp |= DC_HPD4_INT_CONTROL__DC_HPD4_INT_POLARITY_MASK; -		WREG32(mmDC_HPD4_INT_CONTROL, tmp); -		break; -	case AMDGPU_HPD_5: -		tmp = RREG32(mmDC_HPD5_INT_CONTROL); -		if (connected) -			tmp &= ~DC_HPD5_INT_CONTROL__DC_HPD5_INT_POLARITY_MASK; -		else -			tmp |= DC_HPD5_INT_CONTROL__DC_HPD5_INT_POLARITY_MASK; -		WREG32(mmDC_HPD5_INT_CONTROL, tmp); -			break; -	case AMDGPU_HPD_6: -		tmp = RREG32(mmDC_HPD6_INT_CONTROL); -		if (connected) -			tmp &= ~DC_HPD6_INT_CONTROL__DC_HPD6_INT_POLARITY_MASK; -		else -			tmp |= DC_HPD6_INT_CONTROL__DC_HPD6_INT_POLARITY_MASK; -		WREG32(mmDC_HPD6_INT_CONTROL, tmp); -		break; -	default: -		break; -	} +	if (hpd >= adev->mode_info.num_hpd) +		return; + +	tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]); +	if (connected) +		tmp &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_POLARITY_MASK; +	else +		tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_POLARITY_MASK; +	WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);  }  /** @@ -388,13 +327,18 @@ static void dce_v8_0_hpd_init(struct amdgpu_device *adev)  {  	struct drm_device *dev = adev->ddev;  	struct drm_connector *connector; -	u32 tmp = (0x9c4 << DC_HPD1_CONTROL__DC_HPD1_CONNECTION_TIMER__SHIFT) | -		(0xfa << DC_HPD1_CONTROL__DC_HPD1_RX_INT_TIMER__SHIFT) | -		DC_HPD1_CONTROL__DC_HPD1_EN_MASK; +	u32 tmp;  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {  		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); +		if (amdgpu_connector->hpd.hpd >= adev->mode_info.num_hpd) +			continue; + +		tmp = RREG32(mmDC_HPD1_CONTROL + hpd_offsets[amdgpu_connector->hpd.hpd]); +		tmp |= DC_HPD1_CONTROL__DC_HPD1_EN_MASK; +		WREG32(mmDC_HPD1_CONTROL + hpd_offsets[amdgpu_connector->hpd.hpd], tmp); +  		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||  		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {  			/* don't try to enable hpd on eDP or LVDS avoid breaking the @@ -402,30 +346,12 @@ static void dce_v8_0_hpd_init(struct amdgpu_device *adev)  			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143  			 * also avoid interrupt storms during dpms.  			 */ +			tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[amdgpu_connector->hpd.hpd]); +			tmp &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK; +			WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[amdgpu_connector->hpd.hpd], tmp);  			continue;  		} -		switch (amdgpu_connector->hpd.hpd) { -		case AMDGPU_HPD_1: -			WREG32(mmDC_HPD1_CONTROL, tmp); -			break; -		case AMDGPU_HPD_2: -			WREG32(mmDC_HPD2_CONTROL, tmp); -			break; -		case AMDGPU_HPD_3: -			WREG32(mmDC_HPD3_CONTROL, tmp); -			break; -		case AMDGPU_HPD_4: -			WREG32(mmDC_HPD4_CONTROL, tmp); -			break; -		case AMDGPU_HPD_5: -			WREG32(mmDC_HPD5_CONTROL, tmp); -			break; -		case AMDGPU_HPD_6: -			WREG32(mmDC_HPD6_CONTROL, tmp); -			break; -		default: -			break; -		} +  		dce_v8_0_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd);  		amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector->hpd.hpd);  	} @@ -443,32 +369,18 @@ static void dce_v8_0_hpd_fini(struct amdgpu_device *adev)  {  	struct drm_device *dev = adev->ddev;  	struct drm_connector *connector; +	u32 tmp;  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {  		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); -		switch (amdgpu_connector->hpd.hpd) { -		case AMDGPU_HPD_1: -			WREG32(mmDC_HPD1_CONTROL, 0); -			break; -		case AMDGPU_HPD_2: -			WREG32(mmDC_HPD2_CONTROL, 0); -			break; -		case AMDGPU_HPD_3: -			WREG32(mmDC_HPD3_CONTROL, 0); -			break; -		case AMDGPU_HPD_4: -			WREG32(mmDC_HPD4_CONTROL, 0); -			break; -		case AMDGPU_HPD_5: -			WREG32(mmDC_HPD5_CONTROL, 0); -			break; -		case AMDGPU_HPD_6: -			WREG32(mmDC_HPD6_CONTROL, 0); -			break; -		default: -			break; -		} +		if (amdgpu_connector->hpd.hpd >= adev->mode_info.num_hpd) +			continue; + +		tmp = RREG32(mmDC_HPD1_CONTROL + hpd_offsets[amdgpu_connector->hpd.hpd]); +		tmp &= ~DC_HPD1_CONTROL__DC_HPD1_EN_MASK; +		WREG32(mmDC_HPD1_CONTROL + hpd_offsets[amdgpu_connector->hpd.hpd], 0); +  		amdgpu_irq_put(adev, &adev->hpd_irq, amdgpu_connector->hpd.hpd);  	}  } @@ -604,6 +516,52 @@ static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,  	WREG32(mmVGA_RENDER_CONTROL, tmp);  } +static int dce_v8_0_get_num_crtc(struct amdgpu_device *adev) +{ +	int num_crtc = 0; + +	switch (adev->asic_type) { +	case CHIP_BONAIRE: +	case CHIP_HAWAII: +		num_crtc = 6; +		break; +	case CHIP_KAVERI: +		num_crtc = 4; +		break; +	case CHIP_KABINI: +	case CHIP_MULLINS: +		num_crtc = 2; +		break; +	default: +		num_crtc = 0; +	} +	return num_crtc; +} + +void dce_v8_0_disable_dce(struct amdgpu_device *adev) +{ +	/*Disable VGA render and enabled crtc, if has DCE engine*/ +	if (amdgpu_atombios_has_dce_engine_info(adev)) { +		u32 tmp; +		int crtc_enabled, i; + +		dce_v8_0_set_vga_render_state(adev, false); + +		/*Disable crtc*/ +		for (i = 0; i < dce_v8_0_get_num_crtc(adev); i++) { +			crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]), +									 CRTC_CONTROL, CRTC_MASTER_EN); +			if (crtc_enabled) { +				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1); +				tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]); +				tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0); +				WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp); +				WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0); +			} +		} +	} +} +  static void dce_v8_0_program_fmt(struct drm_encoder *encoder)  {  	struct drm_device *dev = encoder->dev; @@ -1501,13 +1459,13 @@ static void dce_v8_0_audio_write_sad_regs(struct drm_encoder *encoder)  			if (sad->format == eld_reg_to_type[i][1]) {  				if (sad->channels > max_channels) { -				value = (sad->channels << -				 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__MAX_CHANNELS__SHIFT) | -				(sad->byte2 << -				 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__DESCRIPTOR_BYTE_2__SHIFT) | -				(sad->freq << -				 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__SUPPORTED_FREQUENCIES__SHIFT); -				max_channels = sad->channels; +					value = (sad->channels << +						 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__MAX_CHANNELS__SHIFT) | +					        (sad->byte2 << +						 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__DESCRIPTOR_BYTE_2__SHIFT) | +					        (sad->freq << +						 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0__SUPPORTED_FREQUENCIES__SHIFT); +					max_channels = sad->channels;  				}  				if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) @@ -1613,7 +1571,7 @@ static void dce_v8_0_afmt_update_ACR(struct drm_encoder *encoder, uint32_t clock  	struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;  	uint32_t offset = dig->afmt->offset; -	WREG32(mmHDMI_ACR_32_0 + offset, (acr.cts_32khz << HDMI_ACR_44_0__HDMI_ACR_CTS_44__SHIFT)); +	WREG32(mmHDMI_ACR_32_0 + offset, (acr.cts_32khz << HDMI_ACR_32_0__HDMI_ACR_CTS_32__SHIFT));  	WREG32(mmHDMI_ACR_32_1 + offset, acr.n_32khz);  	WREG32(mmHDMI_ACR_44_0 + offset, (acr.cts_44_1khz << HDMI_ACR_44_0__HDMI_ACR_CTS_44__SHIFT)); @@ -1693,6 +1651,7 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,  	/* Silent, r600_hdmi_enable will raise WARN for us */  	if (!dig->afmt->enabled)  		return; +  	offset = dig->afmt->offset;  	/* hdmi deep color mode general control packets setup, if bpc > 8 */ @@ -1817,7 +1776,7 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,  	WREG32_OR(mmHDMI_INFOFRAME_CONTROL0 + offset,  		  HDMI_INFOFRAME_CONTROL0__HDMI_AVI_INFO_SEND_MASK | /* enable AVI info frames */ -		  HDMI_INFOFRAME_CONTROL0__HDMI_AVI_INFO_SEND_MASK); /* required for audio info values to be updated */ +		  HDMI_INFOFRAME_CONTROL0__HDMI_AVI_INFO_CONT_MASK); /* required for audio info values to be updated */  	WREG32_P(mmHDMI_INFOFRAME_CONTROL1 + offset,  		 (2 << HDMI_INFOFRAME_CONTROL1__HDMI_AVI_INFO_LINE__SHIFT), /* anything other than 0 */ @@ -1826,13 +1785,12 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,  	WREG32_OR(mmAFMT_AUDIO_PACKET_CONTROL + offset,  		  AFMT_AUDIO_PACKET_CONTROL__AFMT_AUDIO_SAMPLE_SEND_MASK); /* send audio packets */ -	/* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */  	WREG32(mmAFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF);  	WREG32(mmAFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);  	WREG32(mmAFMT_RAMP_CONTROL2 + offset, 0x00000001);  	WREG32(mmAFMT_RAMP_CONTROL3 + offset, 0x00000001); -	/* enable audio after to setting up hw */ +	/* enable audio after setting up hw */  	dce_v8_0_audio_enable(adev, dig->afmt->pin, true);  } @@ -1944,7 +1902,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,  	struct amdgpu_framebuffer *amdgpu_fb;  	struct drm_framebuffer *target_fb;  	struct drm_gem_object *obj; -	struct amdgpu_bo *rbo; +	struct amdgpu_bo *abo;  	uint64_t fb_location, tiling_flags;  	uint32_t fb_format, fb_pitch_pixels;  	u32 fb_swap = (GRPH_ENDIAN_NONE << GRPH_SWAP_CNTL__GRPH_ENDIAN_SWAP__SHIFT); @@ -1952,6 +1910,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,  	u32 viewport_w, viewport_h;  	int r;  	bool bypass_lut = false; +	struct drm_format_name_buf format_name;  	/* no fb bound */  	if (!atomic && !crtc->primary->fb) { @@ -1971,23 +1930,23 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,  	 * just update base pointers  	 */  	obj = amdgpu_fb->obj; -	rbo = gem_to_amdgpu_bo(obj); -	r = amdgpu_bo_reserve(rbo, false); +	abo = gem_to_amdgpu_bo(obj); +	r = amdgpu_bo_reserve(abo, false);  	if (unlikely(r != 0))  		return r;  	if (atomic) { -		fb_location = amdgpu_bo_gpu_offset(rbo); +		fb_location = amdgpu_bo_gpu_offset(abo);  	} else { -		r = amdgpu_bo_pin(rbo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); +		r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location);  		if (unlikely(r != 0)) { -			amdgpu_bo_unreserve(rbo); +			amdgpu_bo_unreserve(abo);  			return -EINVAL;  		}  	} -	amdgpu_bo_get_tiling_flags(rbo, &tiling_flags); -	amdgpu_bo_unreserve(rbo); +	amdgpu_bo_get_tiling_flags(abo, &tiling_flags); +	amdgpu_bo_unreserve(abo);  	pipe_config = AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); @@ -1999,7 +1958,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,  	case DRM_FORMAT_XRGB4444:  	case DRM_FORMAT_ARGB4444:  		fb_format = ((GRPH_DEPTH_16BPP << GRPH_CONTROL__GRPH_DEPTH__SHIFT) | -			     (GRPH_FORMAT_ARGB1555 << GRPH_CONTROL__GRPH_FORMAT__SHIFT)); +			     (GRPH_FORMAT_ARGB4444 << GRPH_CONTROL__GRPH_FORMAT__SHIFT));  #ifdef __BIG_ENDIAN  		fb_swap = (GRPH_ENDIAN_8IN16 << GRPH_SWAP_CNTL__GRPH_ENDIAN_SWAP__SHIFT);  #endif @@ -2057,7 +2016,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,  		break;  	default:  		DRM_ERROR("Unsupported screen format %s\n", -			  drm_get_format_name(target_fb->pixel_format)); +		          drm_get_format_name(target_fb->pixel_format, &format_name));  		return -EINVAL;  	} @@ -2137,17 +2096,17 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,  	WREG32(mmVIEWPORT_SIZE + amdgpu_crtc->crtc_offset,  	       (viewport_w << 16) | viewport_h); -	/* set pageflip to happen only at start of vblank interval (front porch) */ -	WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 3); +	/* set pageflip to happen anywhere in vblank interval */ +	WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);  	if (!atomic && fb && fb != crtc->primary->fb) {  		amdgpu_fb = to_amdgpu_framebuffer(fb); -		rbo = gem_to_amdgpu_bo(amdgpu_fb->obj); -		r = amdgpu_bo_reserve(rbo, false); +		abo = gem_to_amdgpu_bo(amdgpu_fb->obj); +		r = amdgpu_bo_reserve(abo, false);  		if (unlikely(r != 0))  			return r; -		amdgpu_bo_unpin(rbo); -		amdgpu_bo_unreserve(rbo); +		amdgpu_bo_unpin(abo); +		amdgpu_bo_unreserve(abo);  	}  	/* Bytes per pixel may have changed */ @@ -2385,6 +2344,9 @@ static int dce_v8_0_cursor_move_locked(struct drm_crtc *crtc,  	struct amdgpu_device *adev = crtc->dev->dev_private;  	int xorigin = 0, yorigin = 0; +	amdgpu_crtc->cursor_x = x; +	amdgpu_crtc->cursor_y = y; +  	/* avivo cursor are offset into the total surface */  	x += crtc->x;  	y += crtc->y; @@ -2401,11 +2363,6 @@ static int dce_v8_0_cursor_move_locked(struct drm_crtc *crtc,  	WREG32(mmCUR_POSITION + amdgpu_crtc->crtc_offset, (x << 16) | y);  	WREG32(mmCUR_HOT_SPOT + amdgpu_crtc->crtc_offset, (xorigin << 16) | yorigin); -	WREG32(mmCUR_SIZE + amdgpu_crtc->crtc_offset, -	       ((amdgpu_crtc->cursor_width - 1) << 16) | (amdgpu_crtc->cursor_height - 1)); - -	amdgpu_crtc->cursor_x = x; -	amdgpu_crtc->cursor_y = y;  	return 0;  } @@ -2431,6 +2388,7 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,  				     int32_t hot_y)  {  	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); +	struct amdgpu_device *adev = crtc->dev->dev_private;  	struct drm_gem_object *obj;  	struct amdgpu_bo *aobj;  	int ret; @@ -2469,9 +2427,6 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,  		return ret;  	} -	amdgpu_crtc->cursor_width = width; -	amdgpu_crtc->cursor_height = height; -  	dce_v8_0_lock_cursor(crtc, true);  	if (hot_x != amdgpu_crtc->cursor_hot_x || @@ -2487,6 +2442,14 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,  		amdgpu_crtc->cursor_hot_y = hot_y;  	} +	if (width != amdgpu_crtc->cursor_width || +	    height != amdgpu_crtc->cursor_height) { +		WREG32(mmCUR_SIZE + amdgpu_crtc->crtc_offset, +		       (width - 1) << 16 | (height - 1)); +		amdgpu_crtc->cursor_width = width; +		amdgpu_crtc->cursor_height = height; +	} +  	dce_v8_0_show_cursor(crtc);  	dce_v8_0_lock_cursor(crtc, false); @@ -2508,6 +2471,7 @@ unpin:  static void dce_v8_0_cursor_reset(struct drm_crtc *crtc)  {  	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); +	struct amdgpu_device *adev = crtc->dev->dev_private;  	if (amdgpu_crtc->cursor_bo) {  		dce_v8_0_lock_cursor(crtc, true); @@ -2515,6 +2479,10 @@ static void dce_v8_0_cursor_reset(struct drm_crtc *crtc)  		dce_v8_0_cursor_move_locked(crtc, amdgpu_crtc->cursor_x,  					    amdgpu_crtc->cursor_y); +		WREG32(mmCUR_SIZE + amdgpu_crtc->crtc_offset, +		       (amdgpu_crtc->cursor_width - 1) << 16 | +		       (amdgpu_crtc->cursor_height - 1)); +  		dce_v8_0_show_cursor(crtc);  		dce_v8_0_lock_cursor(crtc, false); @@ -2552,7 +2520,7 @@ static const struct drm_crtc_funcs dce_v8_0_crtc_funcs = {  	.gamma_set = dce_v8_0_crtc_gamma_set,  	.set_config = amdgpu_crtc_set_config,  	.destroy = dce_v8_0_crtc_destroy, -	.page_flip = amdgpu_crtc_page_flip, +	.page_flip_target = amdgpu_crtc_page_flip_target,  };  static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode) @@ -2619,16 +2587,16 @@ static void dce_v8_0_crtc_disable(struct drm_crtc *crtc)  	if (crtc->primary->fb) {  		int r;  		struct amdgpu_framebuffer *amdgpu_fb; -		struct amdgpu_bo *rbo; +		struct amdgpu_bo *abo;  		amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); -		rbo = gem_to_amdgpu_bo(amdgpu_fb->obj); -		r = amdgpu_bo_reserve(rbo, false); +		abo = gem_to_amdgpu_bo(amdgpu_fb->obj); +		r = amdgpu_bo_reserve(abo, false);  		if (unlikely(r)) -			DRM_ERROR("failed to reserve rbo before unpin\n"); +			DRM_ERROR("failed to reserve abo before unpin\n");  		else { -			amdgpu_bo_unpin(rbo); -			amdgpu_bo_unreserve(rbo); +			amdgpu_bo_unpin(abo); +			amdgpu_bo_unreserve(abo);  		}  	}  	/* disable the GRPH */ @@ -2653,7 +2621,7 @@ static void dce_v8_0_crtc_disable(struct drm_crtc *crtc)  	case ATOM_PPLL2:  		/* disable the ppll */  		amdgpu_atombios_crtc_program_pll(crtc, amdgpu_crtc->crtc_id, amdgpu_crtc->pll_id, -					  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); +                                                 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);  		break;  	case ATOM_PPLL0:  		/* disable the ppll */ @@ -2803,21 +2771,20 @@ static int dce_v8_0_early_init(void *handle)  	dce_v8_0_set_display_funcs(adev);  	dce_v8_0_set_irq_funcs(adev); +	adev->mode_info.num_crtc = dce_v8_0_get_num_crtc(adev); +  	switch (adev->asic_type) {  	case CHIP_BONAIRE:  	case CHIP_HAWAII: -		adev->mode_info.num_crtc = 6;  		adev->mode_info.num_hpd = 6;  		adev->mode_info.num_dig = 6;  		break;  	case CHIP_KAVERI: -		adev->mode_info.num_crtc = 4;  		adev->mode_info.num_hpd = 6;  		adev->mode_info.num_dig = 7;  		break;  	case CHIP_KABINI:  	case CHIP_MULLINS: -		adev->mode_info.num_crtc = 2;  		adev->mode_info.num_hpd = 6;  		adev->mode_info.num_dig = 6; /* ? */  		break; @@ -2954,10 +2921,6 @@ static int dce_v8_0_hw_fini(void *handle)  static int dce_v8_0_suspend(void *handle)  { -	struct amdgpu_device *adev = (struct amdgpu_device *)handle; - -	amdgpu_atombios_scratch_regs_save(adev); -  	return dce_v8_0_hw_fini(handle);  } @@ -2968,8 +2931,6 @@ static int dce_v8_0_resume(void *handle)  	ret = dce_v8_0_hw_init(handle); -	amdgpu_atombios_scratch_regs_restore(adev); -  	/* turn on the BL */  	if (adev->mode_info.bl_encoder) {  		u8 bl_level = amdgpu_display_backlight_get_level(adev, @@ -3125,42 +3086,23 @@ static int dce_v8_0_set_hpd_interrupt_state(struct amdgpu_device *adev,  					    unsigned type,  					    enum amdgpu_interrupt_state state)  { -	u32 dc_hpd_int_cntl_reg, dc_hpd_int_cntl; +	u32 dc_hpd_int_cntl; -	switch (type) { -	case AMDGPU_HPD_1: -		dc_hpd_int_cntl_reg = mmDC_HPD1_INT_CONTROL; -		break; -	case AMDGPU_HPD_2: -		dc_hpd_int_cntl_reg = mmDC_HPD2_INT_CONTROL; -		break; -	case AMDGPU_HPD_3: -		dc_hpd_int_cntl_reg = mmDC_HPD3_INT_CONTROL; -		break; -	case AMDGPU_HPD_4: -		dc_hpd_int_cntl_reg = mmDC_HPD4_INT_CONTROL; -		break; -	case AMDGPU_HPD_5: -		dc_hpd_int_cntl_reg = mmDC_HPD5_INT_CONTROL; -		break; -	case AMDGPU_HPD_6: -		dc_hpd_int_cntl_reg = mmDC_HPD6_INT_CONTROL; -		break; -	default: +	if (type >= adev->mode_info.num_hpd) {  		DRM_DEBUG("invalid hdp %d\n", type);  		return 0;  	}  	switch (state) {  	case AMDGPU_IRQ_STATE_DISABLE: -		dc_hpd_int_cntl = RREG32(dc_hpd_int_cntl_reg); +		dc_hpd_int_cntl = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[type]);  		dc_hpd_int_cntl &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK; -		WREG32(dc_hpd_int_cntl_reg, dc_hpd_int_cntl); +		WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[type], dc_hpd_int_cntl);  		break;  	case AMDGPU_IRQ_STATE_ENABLE: -		dc_hpd_int_cntl = RREG32(dc_hpd_int_cntl_reg); +		dc_hpd_int_cntl = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[type]);  		dc_hpd_int_cntl |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK; -		WREG32(dc_hpd_int_cntl_reg, dc_hpd_int_cntl); +		WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[type], dc_hpd_int_cntl);  		break;  	default:  		break; @@ -3236,7 +3178,6 @@ static int dce_v8_0_crtc_irq(struct amdgpu_device *adev,  			drm_handle_vblank(adev->ddev, crtc);  		}  		DRM_DEBUG("IH: D%d vblank\n", crtc + 1); -  		break;  	case 1: /* vline */  		if (disp_int & interrupt_status_offsets[crtc].vline) @@ -3245,7 +3186,6 @@ static int dce_v8_0_crtc_irq(struct amdgpu_device *adev,  			DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");  		DRM_DEBUG("IH: D%d vline\n", crtc + 1); -  		break;  	default:  		DRM_DEBUG("Unhandled interrupt: %d %d\n", entry->src_id, entry->src_data); @@ -3335,7 +3275,7 @@ static int dce_v8_0_hpd_irq(struct amdgpu_device *adev,  			    struct amdgpu_irq_src *source,  			    struct amdgpu_iv_entry *entry)  { -	uint32_t disp_int, mask, int_control, tmp; +	uint32_t disp_int, mask, tmp;  	unsigned hpd;  	if (entry->src_data >= adev->mode_info.num_hpd) { @@ -3346,12 +3286,11 @@ static int dce_v8_0_hpd_irq(struct amdgpu_device *adev,  	hpd = entry->src_data;  	disp_int = RREG32(interrupt_status_offsets[hpd].reg);  	mask = interrupt_status_offsets[hpd].hpd; -	int_control = hpd_int_control_offsets[hpd];  	if (disp_int & mask) { -		tmp = RREG32(int_control); +		tmp = RREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd]);  		tmp |= DC_HPD1_INT_CONTROL__DC_HPD1_INT_ACK_MASK; -		WREG32(int_control, tmp); +		WREG32(mmDC_HPD1_INT_CONTROL + hpd_offsets[hpd], tmp);  		schedule_work(&adev->hotplug_work);  		DRM_DEBUG("IH: HPD%d\n", hpd + 1);  	} @@ -3372,7 +3311,7 @@ static int dce_v8_0_set_powergating_state(void *handle,  	return 0;  } -const struct amd_ip_funcs dce_v8_0_ip_funcs = { +static const struct amd_ip_funcs dce_v8_0_ip_funcs = {  	.name = "dce_v8_0",  	.early_init = dce_v8_0_early_init,  	.late_init = NULL, @@ -3656,7 +3595,6 @@ static const struct amdgpu_display_funcs dce_v8_0_display_funcs = {  	.bandwidth_update = &dce_v8_0_bandwidth_update,  	.vblank_get_counter = &dce_v8_0_vblank_get_counter,  	.vblank_wait = &dce_v8_0_vblank_wait, -	.is_display_hung = &dce_v8_0_is_display_hung,  	.backlight_set_level = &amdgpu_atombios_encoder_set_backlight_level,  	.backlight_get_level = &amdgpu_atombios_encoder_get_backlight_level,  	.hpd_sense = &dce_v8_0_hpd_sense, @@ -3702,3 +3640,48 @@ static void dce_v8_0_set_irq_funcs(struct amdgpu_device *adev)  	adev->hpd_irq.num_types = AMDGPU_HPD_LAST;  	adev->hpd_irq.funcs = &dce_v8_0_hpd_irq_funcs;  } + +const struct amdgpu_ip_block_version dce_v8_0_ip_block = +{ +	.type = AMD_IP_BLOCK_TYPE_DCE, +	.major = 8, +	.minor = 0, +	.rev = 0, +	.funcs = &dce_v8_0_ip_funcs, +}; + +const struct amdgpu_ip_block_version dce_v8_1_ip_block = +{ +	.type = AMD_IP_BLOCK_TYPE_DCE, +	.major = 8, +	.minor = 1, +	.rev = 0, +	.funcs = &dce_v8_0_ip_funcs, +}; + +const struct amdgpu_ip_block_version dce_v8_2_ip_block = +{ +	.type = AMD_IP_BLOCK_TYPE_DCE, +	.major = 8, +	.minor = 2, +	.rev = 0, +	.funcs = &dce_v8_0_ip_funcs, +}; + +const struct amdgpu_ip_block_version dce_v8_3_ip_block = +{ +	.type = AMD_IP_BLOCK_TYPE_DCE, +	.major = 8, +	.minor = 3, +	.rev = 0, +	.funcs = &dce_v8_0_ip_funcs, +}; + +const struct amdgpu_ip_block_version dce_v8_5_ip_block = +{ +	.type = AMD_IP_BLOCK_TYPE_DCE, +	.major = 8, +	.minor = 5, +	.rev = 0, +	.funcs = &dce_v8_0_ip_funcs, +};  | 
