Commit 92eed291 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-fixes-4.0' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

Radeon fixes for 4.0:
- Fix some fallout from the audio rework
- Fix a possible oops in the CS ioctl
- Fix interlaced modes on DCE8
- Do a posting read in irq_set callbacks to make sure
  interrupts are properly flushed through the pci bridge

* 'drm-fixes-4.0' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: fix interlaced modes on DCE8
  drm/radeon: fix DRM_IOCTL_RADEON_CS oops
  drm/radeon: do a posting read in cik_set_irq
  drm/radeon: do a posting read in si_set_irq
  drm/radeon: do a posting read in evergreen_set_irq
  drm/radeon: do a posting read in r600_set_irq
  drm/radeon: do a posting read in rs600_set_irq
  drm/radeon: do a posting read in r100_set_irq
  radeon/audio: fix DP audio on DCE6
  radeon/audio: fix whitespace
  drm/radeon: adjust audio callback order
  drm/radeon: properly set dto for dp on DCE4/5
  drm/radeon/audio: update EDID derived fields in modeset
  drm/radeon: don't toggle audio state in modeset
  drm/radeon/audio: set mute around state setup
  drm/radeon: assign pin in detect
  drm/radeon: fix the audio dpms callbacks
parents 54c4cd68 77ae5f4b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1405,6 +1405,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
	       (x << 16) | y);
	viewport_w = crtc->mode.hdisplay;
	viewport_h = (crtc->mode.vdisplay + 1) & ~1;
	if ((rdev->family >= CHIP_BONAIRE) &&
	    (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE))
		viewport_h *= 2;
	WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
	       (viewport_w << 16) | viewport_h);

+16 −14
Original line number Diff line number Diff line
@@ -1626,7 +1626,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
	struct radeon_connector *radeon_connector = NULL;
	struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
	bool travis_quirk = false;
	int encoder_mode;

	if (connector) {
		radeon_connector = to_radeon_connector(connector);
@@ -1722,13 +1721,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
		}
		break;
	}

	encoder_mode = atombios_get_encoder_mode(encoder);
	if (connector && (radeon_audio != 0) &&
	    ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||
	     (ENCODER_MODE_IS_DP(encoder_mode) &&
	      drm_detect_monitor_audio(radeon_connector_edid(connector)))))
		radeon_audio_dpms(encoder, mode);
}

static void
@@ -1737,10 +1729,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
	struct drm_device *dev = encoder->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
	int encoder_mode = atombios_get_encoder_mode(encoder);

	DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
		  radeon_encoder->encoder_id, mode, radeon_encoder->devices,
		  radeon_encoder->active_device);

	if (connector && (radeon_audio != 0) &&
	    ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||
	     (ENCODER_MODE_IS_DP(encoder_mode) &&
	      drm_detect_monitor_audio(radeon_connector_edid(connector)))))
		radeon_audio_dpms(encoder, mode);

	switch (radeon_encoder->encoder_id) {
	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -2170,12 +2171,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
		/* handled in dpms */
		encoder_mode = atombios_get_encoder_mode(encoder);
		if (connector && (radeon_audio != 0) &&
		    ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||
		     (ENCODER_MODE_IS_DP(encoder_mode) &&
		      drm_detect_monitor_audio(radeon_connector_edid(connector)))))
			radeon_audio_mode_set(encoder, adjusted_mode);
		break;
	case ENCODER_OBJECT_ID_INTERNAL_DDI:
	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
@@ -2197,6 +2192,13 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
	}

	atombios_apply_encoder_quirks(encoder, adjusted_mode);

	encoder_mode = atombios_get_encoder_mode(encoder);
	if (connector && (radeon_audio != 0) &&
	    ((encoder_mode == ATOM_ENCODER_MODE_HDMI) ||
	     (ENCODER_MODE_IS_DP(encoder_mode) &&
	      drm_detect_monitor_audio(radeon_connector_edid(connector)))))
		radeon_audio_mode_set(encoder, adjusted_mode);
}

static bool
+3 −0
Original line number Diff line number Diff line
@@ -7555,6 +7555,9 @@ int cik_irq_set(struct radeon_device *rdev)
	WREG32(DC_HPD5_INT_CONTROL, hpd5);
	WREG32(DC_HPD6_INT_CONTROL, hpd6);

	/* posting read */
	RREG32(SRBM_STATUS);

	return 0;
}

+33 −35
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@
#include "radeon_audio.h"
#include "sid.h"

#define DCE8_DCCG_AUDIO_DTO1_PHASE	0x05b8
#define DCE8_DCCG_AUDIO_DTO1_MODULE	0x05bc

u32 dce6_endpoint_rreg(struct radeon_device *rdev,
			      u32 block_offset, u32 reg)
{
@@ -284,40 +287,35 @@ void dce6_dp_audio_set_dto(struct radeon_device *rdev,
	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
	 */
	if (ASIC_IS_DCE8(rdev)) {
		WREG32(DCE8_DCCG_AUDIO_DTO1_PHASE, 24000);
		WREG32(DCE8_DCCG_AUDIO_DTO1_MODULE, clock);
	} else {
		WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
		WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
	}
}

void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable)
void dce6_dp_enable(struct drm_encoder *encoder, bool enable)
{
	struct drm_device *dev = encoder->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
	uint32_t offset;

	if (!dig || !dig->afmt)
		return;

	offset = dig->afmt->offset;

	if (enable) {
        if (dig->afmt->enabled)
            return;

		WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));
		WREG32(EVERGREEN_DP_SEC_CNTL + offset,
		WREG32(EVERGREEN_DP_SEC_TIMESTAMP + dig->afmt->offset,
		       EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));
		WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset,
		       EVERGREEN_DP_SEC_ASP_ENABLE |		/* Audio packet transmission */
		       EVERGREEN_DP_SEC_ATP_ENABLE |		/* Audio timestamp packet transmission */
		       EVERGREEN_DP_SEC_AIP_ENABLE |		/* Audio infoframe packet transmission */
		       EVERGREEN_DP_SEC_STREAM_ENABLE);	/* Master enable for secondary stream engine */
		radeon_audio_enable(rdev, dig->afmt->pin, true);
	} else {
		if (!dig->afmt->enabled)
			return;

		WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0);
		radeon_audio_enable(rdev, dig->afmt->pin, false);
		WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset, 0);
	}

	dig->afmt->enabled = enable;
+3 −0
Original line number Diff line number Diff line
@@ -4593,6 +4593,9 @@ int evergreen_irq_set(struct radeon_device *rdev)
	WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, afmt5);
	WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6);

	/* posting read */
	RREG32(SRBM_STATUS);

	return 0;
}

Loading