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

Most just regression fixes for audio, dpm, and uvd, plus
a resource leak fix for cik.

* 'drm-fixes-3.12' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon/audio: don't set speaker allocation on DCE4+
  drm/radeon: rework audio option
  drm/radeon/audio: don't set speaker allocation on DCE3.2
  drm/radeon: make missing smc ucode non-fatal (CI)
  drm/radeon: make missing smc ucode non-fatal (r7xx-SI)
  drm/radeon/uvd: revert lower msg&fb buffer requirements on UVD3
  drm/radeon: stop the leaks in cik_ib_test
  drm/radeon/atom: workaround vbios bug in transmitter table on rs780
This commit is contained in:
Dave Airlie 2013-10-22 07:35:17 +01:00
commit 579123fdfc
13 changed files with 80 additions and 37 deletions

View File

@ -707,24 +707,37 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
switch (connector->connector_type) { switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) || if (radeon_audio != 0) {
(drm_detect_hdmi_monitor(radeon_connector->edid) && if (radeon_connector->use_digital &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))) (radeon_connector->audio == RADEON_AUDIO_ENABLE))
return ATOM_ENCODER_MODE_HDMI; return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital) else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital)
return ATOM_ENCODER_MODE_DVI;
else
return ATOM_ENCODER_MODE_CRT;
} else if (radeon_connector->use_digital) {
return ATOM_ENCODER_MODE_DVI; return ATOM_ENCODER_MODE_DVI;
else } else {
return ATOM_ENCODER_MODE_CRT; return ATOM_ENCODER_MODE_CRT;
}
break; break;
case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA: case DRM_MODE_CONNECTOR_HDMIA:
default: default:
if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) || if (radeon_audio != 0) {
(drm_detect_hdmi_monitor(radeon_connector->edid) && if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
(radeon_connector->audio == RADEON_AUDIO_AUTO))) return ATOM_ENCODER_MODE_HDMI;
return ATOM_ENCODER_MODE_HDMI; else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
else (radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else
return ATOM_ENCODER_MODE_DVI;
} else {
return ATOM_ENCODER_MODE_DVI; return ATOM_ENCODER_MODE_DVI;
}
break; break;
case DRM_MODE_CONNECTOR_LVDS: case DRM_MODE_CONNECTOR_LVDS:
return ATOM_ENCODER_MODE_LVDS; return ATOM_ENCODER_MODE_LVDS;
@ -732,14 +745,19 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_DisplayPort: case DRM_MODE_CONNECTOR_DisplayPort:
dig_connector = radeon_connector->con_priv; dig_connector = radeon_connector->con_priv;
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
return ATOM_ENCODER_MODE_DP; return ATOM_ENCODER_MODE_DP;
else if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) || } else if (radeon_audio != 0) {
(drm_detect_hdmi_monitor(radeon_connector->edid) && if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
(radeon_connector->audio == RADEON_AUDIO_AUTO))) return ATOM_ENCODER_MODE_HDMI;
return ATOM_ENCODER_MODE_HDMI; else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
else (radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else
return ATOM_ENCODER_MODE_DVI;
} else {
return ATOM_ENCODER_MODE_DVI; return ATOM_ENCODER_MODE_DVI;
}
break; break;
case DRM_MODE_CONNECTOR_eDP: case DRM_MODE_CONNECTOR_eDP:
return ATOM_ENCODER_MODE_DP; return ATOM_ENCODER_MODE_DP;
@ -1655,7 +1673,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
* does the same thing and more. * does the same thing and more.
*/ */
if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) && if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) &&
(rdev->family != CHIP_RS880)) (rdev->family != CHIP_RS780) && (rdev->family != CHIP_RS880))
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
} }
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {

View File

@ -1694,6 +1694,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
fw_name); fw_name);
release_firmware(rdev->smc_fw); release_firmware(rdev->smc_fw);
rdev->smc_fw = NULL; rdev->smc_fw = NULL;
err = 0;
} else if (rdev->smc_fw->size != smc_req_size) { } else if (rdev->smc_fw->size != smc_req_size) {
printk(KERN_ERR printk(KERN_ERR
"cik_smc: Bogus length %zu in firmware \"%s\"\n", "cik_smc: Bogus length %zu in firmware \"%s\"\n",
@ -3182,6 +3183,7 @@ int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256);
if (r) { if (r) {
DRM_ERROR("radeon: failed to get ib (%d).\n", r); DRM_ERROR("radeon: failed to get ib (%d).\n", r);
radeon_scratch_free(rdev, scratch);
return r; return r;
} }
ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
@ -3198,6 +3200,8 @@ int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
r = radeon_fence_wait(ib.fence, false); r = radeon_fence_wait(ib.fence, false);
if (r) { if (r) {
DRM_ERROR("radeon: fence wait failed (%d).\n", r); DRM_ERROR("radeon: fence wait failed (%d).\n", r);
radeon_scratch_free(rdev, scratch);
radeon_ib_free(rdev, &ib);
return r; return r;
} }
for (i = 0; i < rdev->usec_timeout; i++) { for (i = 0; i < rdev->usec_timeout; i++) {

View File

@ -113,6 +113,9 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
u8 *sadb; u8 *sadb;
int sad_count; int sad_count;
/* XXX: setting this register causes hangs on some asics */
return;
if (!dig->afmt->pin) if (!dig->afmt->pin)
return; return;

View File

@ -67,6 +67,9 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
u8 *sadb; u8 *sadb;
int sad_count; int sad_count;
/* XXX: setting this register causes hangs on some asics */
return;
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
if (connector->encoder == encoder) if (connector->encoder == encoder)
radeon_connector = to_radeon_connector(connector); radeon_connector = to_radeon_connector(connector);

View File

@ -804,6 +804,7 @@ int ni_init_microcode(struct radeon_device *rdev)
fw_name); fw_name);
release_firmware(rdev->smc_fw); release_firmware(rdev->smc_fw);
rdev->smc_fw = NULL; rdev->smc_fw = NULL;
err = 0;
} else if (rdev->smc_fw->size != smc_req_size) { } else if (rdev->smc_fw->size != smc_req_size) {
printk(KERN_ERR printk(KERN_ERR
"ni_mc: Bogus length %zu in firmware \"%s\"\n", "ni_mc: Bogus length %zu in firmware \"%s\"\n",

View File

@ -2302,6 +2302,7 @@ int r600_init_microcode(struct radeon_device *rdev)
fw_name); fw_name);
release_firmware(rdev->smc_fw); release_firmware(rdev->smc_fw);
rdev->smc_fw = NULL; rdev->smc_fw = NULL;
err = 0;
} else if (rdev->smc_fw->size != smc_req_size) { } else if (rdev->smc_fw->size != smc_req_size) {
printk(KERN_ERR printk(KERN_ERR
"smc: Bogus length %zu in firmware \"%s\"\n", "smc: Bogus length %zu in firmware \"%s\"\n",

View File

@ -309,6 +309,9 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder)
u8 *sadb; u8 *sadb;
int sad_count; int sad_count;
/* XXX: setting this register causes hangs on some asics */
return;
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
if (connector->encoder == encoder) if (connector->encoder == encoder)
radeon_connector = to_radeon_connector(connector); radeon_connector = to_radeon_connector(connector);

View File

@ -1658,9 +1658,12 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base, drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
drm_object_attach_property(&radeon_connector->base.base, if (radeon_audio != 0)
rdev->mode_info.audio_property, drm_object_attach_property(&radeon_connector->base.base,
RADEON_AUDIO_DISABLE); rdev->mode_info.audio_property,
(radeon_audio == 1) ?
RADEON_AUDIO_AUTO :
RADEON_AUDIO_DISABLE);
subpixel_order = SubPixelHorizontalRGB; subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true; connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB) if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
@ -1754,10 +1757,12 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
} }
if (ASIC_IS_DCE2(rdev)) { if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base, drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property, rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE); (radeon_audio == 1) ?
RADEON_AUDIO_AUTO :
RADEON_AUDIO_DISABLE);
} }
if (connector_type == DRM_MODE_CONNECTOR_DVII) { if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true; radeon_connector->dac_load_detect = true;
@ -1799,10 +1804,12 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
} }
if (ASIC_IS_DCE2(rdev)) { if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base, drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property, rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE); (radeon_audio == 1) ?
RADEON_AUDIO_AUTO :
RADEON_AUDIO_DISABLE);
} }
subpixel_order = SubPixelHorizontalRGB; subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true; connector->interlace_allowed = true;
@ -1843,10 +1850,12 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property, rdev->mode_info.underscan_vborder_property,
0); 0);
} }
if (ASIC_IS_DCE2(rdev)) { if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base, drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property, rdev->mode_info.audio_property,
RADEON_AUDIO_DISABLE); (radeon_audio == 1) ?
RADEON_AUDIO_AUTO :
RADEON_AUDIO_DISABLE);
} }
connector->interlace_allowed = true; connector->interlace_allowed = true;
/* in theory with a DP to VGA converter... */ /* in theory with a DP to VGA converter... */

View File

@ -85,9 +85,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
VRAM, also but everything into VRAM on AGP cards to avoid VRAM, also but everything into VRAM on AGP cards to avoid
image corruptions */ image corruptions */
if (p->ring == R600_RING_TYPE_UVD_INDEX && if (p->ring == R600_RING_TYPE_UVD_INDEX &&
p->rdev->family < CHIP_PALM &&
(i == 0 || drm_pci_device_is_agp(p->rdev->ddev))) { (i == 0 || drm_pci_device_is_agp(p->rdev->ddev))) {
/* TODO: is this still needed for NI+ ? */
p->relocs[i].lobj.domain = p->relocs[i].lobj.domain =
RADEON_GEM_DOMAIN_VRAM; RADEON_GEM_DOMAIN_VRAM;

View File

@ -153,7 +153,7 @@ int radeon_benchmarking = 0;
int radeon_testing = 0; int radeon_testing = 0;
int radeon_connector_table = 0; int radeon_connector_table = 0;
int radeon_tv = 1; int radeon_tv = 1;
int radeon_audio = 1; int radeon_audio = -1;
int radeon_disp_priority = 0; int radeon_disp_priority = 0;
int radeon_hw_i2c = 0; int radeon_hw_i2c = 0;
int radeon_pcie_gen2 = -1; int radeon_pcie_gen2 = -1;
@ -196,7 +196,7 @@ module_param_named(connector_table, radeon_connector_table, int, 0444);
MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
module_param_named(tv, radeon_tv, int, 0444); module_param_named(tv, radeon_tv, int, 0444);
MODULE_PARM_DESC(audio, "Audio enable (1 = enable)"); MODULE_PARM_DESC(audio, "Audio enable (-1 = auto, 0 = disable, 1 = enable)");
module_param_named(audio, radeon_audio, int, 0444); module_param_named(audio, radeon_audio, int, 0444);
MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)"); MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");

View File

@ -476,7 +476,8 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
return -EINVAL; return -EINVAL;
} }
if (p->rdev->family < CHIP_PALM && (cmd == 0 || cmd == 0x3) && /* TODO: is this still necessary on NI+ ? */
if ((cmd == 0 || cmd == 0x3) &&
(start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) { (start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) {
DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n", DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n",
start, end); start, end);

View File

@ -1681,6 +1681,7 @@ static int si_init_microcode(struct radeon_device *rdev)
fw_name); fw_name);
release_firmware(rdev->smc_fw); release_firmware(rdev->smc_fw);
rdev->smc_fw = NULL; rdev->smc_fw = NULL;
err = 0;
} else if (rdev->smc_fw->size != smc_req_size) { } else if (rdev->smc_fw->size != smc_req_size) {
printk(KERN_ERR printk(KERN_ERR
"si_smc: Bogus length %zu in firmware \"%s\"\n", "si_smc: Bogus length %zu in firmware \"%s\"\n",

View File

@ -212,8 +212,8 @@ int uvd_v1_0_start(struct radeon_device *rdev)
/* enable VCPU clock */ /* enable VCPU clock */
WREG32(UVD_VCPU_CNTL, 1 << 9); WREG32(UVD_VCPU_CNTL, 1 << 9);
/* enable UMC and NC0 */ /* enable UMC */
WREG32_P(UVD_LMI_CTRL2, 1 << 13, ~((1 << 8) | (1 << 13))); WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
/* boot up the VCPU */ /* boot up the VCPU */
WREG32(UVD_SOFT_RESET, 0); WREG32(UVD_SOFT_RESET, 0);