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

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
...@@ -1405,6 +1405,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, ...@@ -1405,6 +1405,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
(x << 16) | y); (x << 16) | y);
viewport_w = crtc->mode.hdisplay; viewport_w = crtc->mode.hdisplay;
viewport_h = (crtc->mode.vdisplay + 1) & ~1; 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, WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
(viewport_w << 16) | viewport_h); (viewport_w << 16) | viewport_h);
......
...@@ -1626,7 +1626,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) ...@@ -1626,7 +1626,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
struct radeon_connector *radeon_connector = NULL; struct radeon_connector *radeon_connector = NULL;
struct radeon_connector_atom_dig *radeon_dig_connector = NULL; struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
bool travis_quirk = false; bool travis_quirk = false;
int encoder_mode;
if (connector) { if (connector) {
radeon_connector = to_radeon_connector(connector); radeon_connector = to_radeon_connector(connector);
...@@ -1722,13 +1721,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) ...@@ -1722,13 +1721,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
} }
break; 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 static void
...@@ -1737,10 +1729,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) ...@@ -1737,10 +1729,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 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", 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->encoder_id, mode, radeon_encoder->devices,
radeon_encoder->active_device); 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) { switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_TMDS1: case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
...@@ -2170,12 +2171,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -2170,12 +2171,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
/* handled in dpms */ /* 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; break;
case ENCODER_OBJECT_ID_INTERNAL_DDI: case ENCODER_OBJECT_ID_INTERNAL_DDI:
case ENCODER_OBJECT_ID_INTERNAL_DVO1: case ENCODER_OBJECT_ID_INTERNAL_DVO1:
...@@ -2197,6 +2192,13 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -2197,6 +2192,13 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
} }
atombios_apply_encoder_quirks(encoder, adjusted_mode); 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 static bool
......
...@@ -7555,6 +7555,9 @@ int cik_irq_set(struct radeon_device *rdev) ...@@ -7555,6 +7555,9 @@ int cik_irq_set(struct radeon_device *rdev)
WREG32(DC_HPD5_INT_CONTROL, hpd5); WREG32(DC_HPD5_INT_CONTROL, hpd5);
WREG32(DC_HPD6_INT_CONTROL, hpd6); WREG32(DC_HPD6_INT_CONTROL, hpd6);
/* posting read */
RREG32(SRBM_STATUS);
return 0; return 0;
} }
......
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
#include "radeon_audio.h" #include "radeon_audio.h"
#include "sid.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 dce6_endpoint_rreg(struct radeon_device *rdev,
u32 block_offset, u32 reg) u32 block_offset, u32 reg)
{ {
...@@ -252,72 +255,67 @@ void dce6_audio_enable(struct radeon_device *rdev, ...@@ -252,72 +255,67 @@ void dce6_audio_enable(struct radeon_device *rdev,
void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
struct radeon_crtc *crtc, unsigned int clock) struct radeon_crtc *crtc, unsigned int clock)
{ {
/* Two dtos; generally use dto0 for HDMI */ /* Two dtos; generally use dto0 for HDMI */
u32 value = 0; u32 value = 0;
if (crtc) if (crtc)
value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
WREG32(DCCG_AUDIO_DTO_SOURCE, value); WREG32(DCCG_AUDIO_DTO_SOURCE, value);
/* Express [24MHz / target pixel clock] as an exact rational /* Express [24MHz / target pixel clock] as an exact rational
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
*/ */
WREG32(DCCG_AUDIO_DTO0_PHASE, 24000); WREG32(DCCG_AUDIO_DTO0_PHASE, 24000);
WREG32(DCCG_AUDIO_DTO0_MODULE, clock); WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
} }
void dce6_dp_audio_set_dto(struct radeon_device *rdev, void dce6_dp_audio_set_dto(struct radeon_device *rdev,
struct radeon_crtc *crtc, unsigned int clock) struct radeon_crtc *crtc, unsigned int clock)
{ {
/* Two dtos; generally use dto1 for DP */ /* Two dtos; generally use dto1 for DP */
u32 value = 0; u32 value = 0;
value |= DCCG_AUDIO_DTO_SEL; value |= DCCG_AUDIO_DTO_SEL;
if (crtc) if (crtc)
value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
WREG32(DCCG_AUDIO_DTO_SOURCE, value); WREG32(DCCG_AUDIO_DTO_SOURCE, value);
/* Express [24MHz / target pixel clock] as an exact rational /* Express [24MHz / target pixel clock] as an exact rational
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
*/ */
WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); if (ASIC_IS_DCE8(rdev)) {
WREG32(DCCG_AUDIO_DTO1_MODULE, clock); 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 drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset;
if (!dig || !dig->afmt) if (!dig || !dig->afmt)
return; return;
offset = dig->afmt->offset;
if (enable) { if (enable) {
if (dig->afmt->enabled) WREG32(EVERGREEN_DP_SEC_TIMESTAMP + dig->afmt->offset,
return; EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));
WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset,
WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1)); EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */
WREG32(EVERGREEN_DP_SEC_CNTL + offset, EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */
EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */
EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */
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 { } else {
if (!dig->afmt->enabled) WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset, 0);
return;
WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0);
radeon_audio_enable(rdev, dig->afmt->pin, false);
} }
dig->afmt->enabled = enable; dig->afmt->enabled = enable;
......
...@@ -4593,6 +4593,9 @@ int evergreen_irq_set(struct radeon_device *rdev) ...@@ -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_CRTC4_REGISTER_OFFSET, afmt5);
WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6); WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6);
/* posting read */
RREG32(SRBM_STATUS);
return 0; return 0;
} }
......
...@@ -272,7 +272,7 @@ void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, ...@@ -272,7 +272,7 @@ void dce4_hdmi_audio_set_dto(struct radeon_device *rdev,
} }
void dce4_dp_audio_set_dto(struct radeon_device *rdev, void dce4_dp_audio_set_dto(struct radeon_device *rdev,
struct radeon_crtc *crtc, unsigned int clock) struct radeon_crtc *crtc, unsigned int clock)
{ {
u32 value; u32 value;
...@@ -294,7 +294,7 @@ void dce4_dp_audio_set_dto(struct radeon_device *rdev, ...@@ -294,7 +294,7 @@ void dce4_dp_audio_set_dto(struct radeon_device *rdev,
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
*/ */
WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
WREG32(DCCG_AUDIO_DTO1_MODULE, rdev->clock.max_pixel_clock * 10); WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
} }
void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset) void dce4_set_vbi_packet(struct drm_encoder *encoder, u32 offset)
...@@ -350,20 +350,9 @@ void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset) ...@@ -350,20 +350,9 @@ void dce4_set_audio_packet(struct drm_encoder *encoder, u32 offset)
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
WREG32(HDMI_INFOFRAME_CONTROL0 + offset,
HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */
WREG32(AFMT_INFOFRAME_CONTROL0 + offset, WREG32(AFMT_INFOFRAME_CONTROL0 + offset,
AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */ AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */
WREG32(HDMI_INFOFRAME_CONTROL1 + offset,
HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */
WREG32(HDMI_AUDIO_PACKET_CONTROL + offset,
HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */
HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
WREG32(AFMT_60958_0 + offset, WREG32(AFMT_60958_0 + offset,
AFMT_60958_CS_CHANNEL_NUMBER_L(1)); AFMT_60958_CS_CHANNEL_NUMBER_L(1));
...@@ -408,15 +397,19 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) ...@@ -408,15 +397,19 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
if (!dig || !dig->afmt) if (!dig || !dig->afmt)
return; return;
/* Silent, r600_hdmi_enable will raise WARN for us */ if (enable) {
if (enable && dig->afmt->enabled) WREG32(HDMI_INFOFRAME_CONTROL1 + dig->afmt->offset,
return; HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */
if (!enable && !dig->afmt->enabled)
return; WREG32(HDMI_AUDIO_PACKET_CONTROL + dig->afmt->offset,
HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */
HDMI_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
if (!enable && dig->afmt->pin) { WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset,
radeon_audio_enable(rdev, dig->afmt->pin, 0); HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
dig->afmt->pin = NULL; HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */
} else {
WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset, 0);
} }
dig->afmt->enabled = enable; dig->afmt->enabled = enable;
...@@ -425,33 +418,28 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) ...@@ -425,33 +418,28 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id); enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id);
} }
void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) void evergreen_dp_enable(struct drm_encoder *encoder, bool enable)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t offset;
if (!dig || !dig->afmt) if (!dig || !dig->afmt)
return; return;
offset = dig->afmt->offset;
if (enable) { if (enable) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector; struct radeon_connector_atom_dig *dig_connector;
uint32_t val; uint32_t val;
if (dig->afmt->enabled) WREG32(EVERGREEN_DP_SEC_TIMESTAMP + dig->afmt->offset,
return; EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));
WREG32(EVERGREEN_DP_SEC_TIMESTAMP + offset, EVERGREEN_DP_SEC_TIMESTAMP_MODE(1));
if (radeon_connector->con_priv) { if (radeon_connector->con_priv) {
dig_connector = radeon_connector->con_priv; dig_connector = radeon_connector->con_priv;
val = RREG32(EVERGREEN_DP_SEC_AUD_N + offset); val = RREG32(EVERGREEN_DP_SEC_AUD_N + dig->afmt->offset);
val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf); val &= ~EVERGREEN_DP_SEC_N_BASE_MULTIPLE(0xf);
if (dig_connector->dp_clock == 162000) if (dig_connector->dp_clock == 162000)
...@@ -459,21 +447,16 @@ void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable) ...@@ -459,21 +447,16 @@ void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable)
else else
val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(5); val |= EVERGREEN_DP_SEC_N_BASE_MULTIPLE(5);
WREG32(EVERGREEN_DP_SEC_AUD_N + offset, val); WREG32(EVERGREEN_DP_SEC_AUD_N + dig->afmt->offset, val);
} }
WREG32(EVERGREEN_DP_SEC_CNTL + offset, WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset,
EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */ EVERGREEN_DP_SEC_ASP_ENABLE | /* Audio packet transmission */
EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */ EVERGREEN_DP_SEC_ATP_ENABLE | /* Audio timestamp packet transmission */
EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */ EVERGREEN_DP_SEC_AIP_ENABLE | /* Audio infoframe packet transmission */
EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */ EVERGREEN_DP_SEC_STREAM_ENABLE); /* Master enable for secondary stream engine */
radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
} else { } else {
if (!dig->afmt->enabled) WREG32(EVERGREEN_DP_SEC_CNTL + dig->afmt->offset, 0);
return;
WREG32(EVERGREEN_DP_SEC_CNTL + offset, 0);
radeon_audio_enable(rdev, dig->afmt->pin, 0);
} }
dig->afmt->enabled = enable; dig->afmt->enabled = enable;
......
...@@ -728,6 +728,10 @@ int r100_irq_set(struct radeon_device *rdev) ...@@ -728,6 +728,10 @@ int r100_irq_set(struct radeon_device *rdev)
tmp |= RADEON_FP2_DETECT_MASK; tmp |= RADEON_FP2_DETECT_MASK;
} }
WREG32(RADEON_GEN_INT_CNTL, tmp); WREG32(RADEON_GEN_INT_CNTL, tmp);
/* read back to post the write */
RREG32(RADEON_GEN_INT_CNTL);
return 0; return 0;
} }
......
...@@ -3784,6 +3784,9 @@ int r600_irq_set(struct radeon_device *rdev) ...@@ -3784,6 +3784,9 @@ int r600_irq_set(struct radeon_device *rdev)
WREG32(RV770_CG_THERMAL_INT, thermal_int); WREG32(RV770_CG_THERMAL_INT, thermal_int);
} }
/* posting read */
RREG32(R_000E50_SRBM_STATUS);
return 0; return 0;
} }
......
...@@ -476,17 +476,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) ...@@ -476,17 +476,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
if (!dig || !dig->afmt) if (!dig || !dig->afmt)
return; return;
/* Silent, r600_hdmi_enable will raise WARN for us */
if (enable && dig->afmt->enabled)
return;
if (!enable && !dig->afmt->enabled)
return;
if (!enable && dig->afmt->pin) {
radeon_audio_enable(rdev, dig->afmt->pin, 0);
dig->afmt->pin = NULL;
}
/* Older chipsets require setting HDMI and routing manually */ /* Older chipsets require setting HDMI and routing manually */
if (!ASIC_IS_DCE3(rdev)) { if (!ASIC_IS_DCE3(rdev)) {
if (enable) if (enable)
......
...@@ -101,8 +101,8 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, ...@@ -101,8 +101,8 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode); struct drm_display_mode *mode);
void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); void r600_hdmi_enable(struct drm_encoder *encoder, bool enable);
void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable); void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
void evergreen_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); void evergreen_dp_enable(struct drm_encoder *encoder, bool enable);
void dce6_enable_dp_audio_packets(struct drm_encoder *encoder, bool enable); void dce6_dp_enable(struct drm_encoder *encoder, bool enable);
static const u32 pin_offsets[7] = static const u32 pin_offsets[7] =
{ {
...@@ -210,7 +210,7 @@ static struct radeon_audio_funcs dce4_dp_funcs = { ...@@ -210,7 +210,7 @@ static struct radeon_audio_funcs dce4_dp_funcs = {
.set_avi_packet = evergreen_set_avi_packet, .set_avi_packet = evergreen_set_avi_packet,
.set_audio_packet = dce4_set_audio_packet, .set_audio_packet = dce4_set_audio_packet,
.mode_set = radeon_audio_dp_mode_set, .mode_set = radeon_audio_dp_mode_set,
.dpms = evergreen_enable_dp_audio_packets, .dpms = evergreen_dp_enable,
}; };
static struct radeon_audio_funcs dce6_hdmi_funcs = { static struct radeon_audio_funcs dce6_hdmi_funcs = {
...@@ -240,7 +240,7 @@ static struct radeon_audio_funcs dce6_dp_funcs = { ...@@ -240,7 +240,7 @@ static struct radeon_audio_funcs dce6_dp_funcs = {
.set_avi_packet = evergreen_set_avi_packet, .set_avi_packet = evergreen_set_avi_packet,
.set_audio_packet = dce4_set_audio_packet, .set_audio_packet = dce4_set_audio_packet,
.mode_set = radeon_audio_dp_mode_set, .mode_set = radeon_audio_dp_mode_set,
.dpms = dce6_enable_dp_audio_packets, .dpms = dce6_dp_enable,
}; };
static void radeon_audio_interface_init(struct radeon_device *rdev) static void radeon_audio_interface_init(struct radeon_device *rdev)
...@@ -452,7 +452,7 @@ void radeon_audio_enable(struct radeon_device *rdev, ...@@ -452,7 +452,7 @@ void radeon_audio_enable(struct radeon_device *rdev,
} }
void radeon_audio_detect(struct drm_connector *connector, void radeon_audio_detect(struct drm_connector *connector,
enum drm_connector_status status) enum drm_connector_status status)
{ {
struct radeon_device *rdev; struct radeon_device *rdev;
struct radeon_encoder *radeon_encoder; struct radeon_encoder *radeon_encoder;
...@@ -483,14 +483,11 @@ void radeon_audio_detect(struct drm_connector *connector, ...@@ -483,14 +483,11 @@ void radeon_audio_detect(struct drm_connector *connector,
else else
radeon_encoder->audio = rdev->audio.hdmi_funcs; radeon_encoder->audio = rdev->audio.hdmi_funcs;
radeon_audio_write_speaker_allocation(connector->encoder); dig->afmt->pin = radeon_audio_get_pin(connector->encoder);
radeon_audio_write_sad_regs(connector->encoder);
if (connector->encoder->crtc)
radeon_audio_write_latency_fields(connector->encoder,
&connector->encoder->crtc->mode);
radeon_audio_enable(rdev, dig->afmt->pin, 0xf); radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
} else { } else {
radeon_audio_enable(rdev, dig->afmt->pin, 0); radeon_audio_enable(rdev, dig->afmt->pin, 0);
dig->afmt->pin = NULL;
} }
} }
...@@ -694,23 +691,22 @@ static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute) ...@@ -694,23 +691,22 @@ static void radeon_audio_set_mute(struct drm_encoder *encoder, bool mute)
* update the info frames with the data from the current display mode * update the info frames with the data from the current display mode
*/ */
static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct radeon_device *rdev = encoder->dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
if (!dig || !dig->afmt) if (!dig || !dig->afmt)
return; return;
/* disable audio prior to setting up hw */ radeon_audio_set_mute(encoder, true);
dig->afmt->pin = radeon_audio_get_pin(encoder);
radeon_audio_enable(rdev, dig->afmt->pin, 0);
radeon_audio_write_speaker_allocation(encoder);
radeon_audio_write_sad_regs(encoder);
radeon_audio_write_latency_fields(encoder, mode);
radeon_audio_set_dto(encoder, mode->clock); radeon_audio_set_dto(encoder, mode->clock);
radeon_audio_set_vbi_packet(encoder); radeon_audio_set_vbi_packet(encoder);
radeon_hdmi_set_color_depth(encoder); radeon_hdmi_set_color_depth(encoder);
radeon_audio_set_mute(encoder, false);
radeon_audio_update_acr(encoder, mode->clock); radeon_audio_update_acr(encoder, mode->clock);
radeon_audio_set_audio_packet(encoder); radeon_audio_set_audio_packet(encoder);
radeon_audio_select_pin(encoder); radeon_audio_select_pin(encoder);
...@@ -718,8 +714,7 @@ static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, ...@@ -718,8 +714,7 @@ static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder,
if (radeon_audio_set_avi_packet(encoder, mode) < 0) if (radeon_audio_set_avi_packet(encoder, mode) < 0)
return; return;
/* enable audio after to setting up hw */ radeon_audio_set_mute(encoder, false);
radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
} }
static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
...@@ -729,23 +724,26 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, ...@@ -729,23 +724,26 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector =
radeon_connector->con_priv;
if (!dig || !dig->afmt) if (!dig || !dig->afmt)
return; return;
/* disable audio prior to setting up hw */ radeon_audio_write_speaker_allocation(encoder);
dig->afmt->pin = radeon_audio_get_pin(encoder); radeon_audio_write_sad_regs(encoder);
radeon_audio_enable(rdev, dig->afmt->pin, 0); radeon_audio_write_latency_fields(encoder, mode);
if (rdev->clock.dp_extclk || ASIC_IS_DCE5(rdev))
radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10); radeon_audio_set_dto(encoder, rdev->clock.default_dispclk * 10);
else
radeon_audio_set_dto(encoder, dig_connector->dp_clock);
radeon_audio_set_audio_packet(encoder); radeon_audio_set_audio_packet(encoder);
radeon_audio_select_pin(encoder); radeon_audio_select_pin(encoder);
if (radeon_audio_set_avi_packet(encoder, mode) < 0) if (radeon_audio_set_avi_packet(encoder, mode) < 0)
return; return;
/* enable audio after to setting up hw */
radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
} }
void radeon_audio_mode_set(struct drm_encoder *encoder, void radeon_audio_mode_set(struct drm_encoder *encoder,
......
...@@ -256,11 +256,13 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) ...@@ -256,11 +256,13 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
u32 ring = RADEON_CS_RING_GFX; u32 ring = RADEON_CS_RING_GFX;
s32 priority = 0; s32 priority = 0;
INIT_LIST_HEAD(&p->validated);
if (!cs->num_chunks) { if (!cs->num_chunks) {
return 0; return 0;
} }
/* get chunks */ /* get chunks */
INIT_LIST_HEAD(&p->validated);
p->idx = 0; p->idx = 0;
p->ib.sa_bo = NULL; p->ib.sa_bo = NULL;
p->const_ib.sa_bo = NULL; p->const_ib.sa_bo = NULL;
......
...@@ -694,6 +694,10 @@ int rs600_irq_set(struct radeon_device *rdev) ...@@ -694,6 +694,10 @@ int rs600_irq_set(struct radeon_device *rdev)
WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
if (ASIC_IS_DCE2(rdev)) if (ASIC_IS_DCE2(rdev))
WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0); WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
/* posting read */
RREG32(R_000040_GEN_INT_CNTL);
return 0; return 0;
} }
......
...@@ -6203,6 +6203,9 @@ int si_irq_set(struct radeon_device *rdev) ...@@ -6203,6 +6203,9 @@ int si_irq_set(struct radeon_device *rdev)
WREG32(CG_THERMAL_INT, thermal_int); WREG32(CG_THERMAL_INT, thermal_int);
/* posting read */
RREG32(SRBM_STATUS);
return 0; return 0;
} }
......
...@@ -912,8 +912,8 @@ ...@@ -912,8 +912,8 @@
#define DCCG_AUDIO_DTO0_PHASE 0x05b0 #define DCCG_AUDIO_DTO0_PHASE 0x05b0
#define DCCG_AUDIO_DTO0_MODULE 0x05b4 #define DCCG_AUDIO_DTO0_MODULE 0x05b4
#define DCCG_AUDIO_DTO1_PHASE 0x05b8 #define DCCG_AUDIO_DTO1_PHASE 0x05c0
#define DCCG_AUDIO_DTO1_MODULE 0x05bc #define DCCG_AUDIO_DTO1_MODULE 0x05c4
#define AFMT_AUDIO_SRC_CONTROL 0x713c #define AFMT_AUDIO_SRC_CONTROL 0x713c
#define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0) #define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment