mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
Merge branch 'drm-fixes-3.14' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
more radeon fixes * 'drm-fixes-3.14' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: enable speaker allocation setup on dce3.2 drm/radeon: change audio enable logic drm/radeon: fix audio disable on dce6+ drm/radeon: free uvd ring on unload drm/radeon: disable pll sharing for DP on DCE4.1 drm/radeon: fix missing bo reservation drm/radeon: print the supported atpx function mask
This commit is contained in:
commit
d668ca1cc6
@ -1774,6 +1774,20 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
return ATOM_PPLL1;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else if (ASIC_IS_DCE41(rdev)) {
|
||||
/* Don't share PLLs on DCE4.1 chips */
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
|
||||
if (rdev->clock.dp_extclk)
|
||||
/* skip PPLL programming if using ext clock */
|
||||
return ATOM_PPLL_INVALID;
|
||||
}
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL1)))
|
||||
return ATOM_PPLL1;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else if (ASIC_IS_DCE4(rdev)) {
|
||||
/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
|
||||
* depending on the asic:
|
||||
@ -1801,7 +1815,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
} else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */
|
||||
} else {
|
||||
/* use the same PPLL for all monitors with the same clock */
|
||||
pll = radeon_get_shared_nondp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
|
@ -278,13 +278,15 @@ static int dce6_audio_chipset_supported(struct radeon_device *rdev)
|
||||
return !ASIC_IS_NODCE(rdev);
|
||||
}
|
||||
|
||||
static void dce6_audio_enable(struct radeon_device *rdev,
|
||||
struct r600_audio_pin *pin,
|
||||
bool enable)
|
||||
void dce6_audio_enable(struct radeon_device *rdev,
|
||||
struct r600_audio_pin *pin,
|
||||
bool enable)
|
||||
{
|
||||
if (!pin)
|
||||
return;
|
||||
|
||||
WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL,
|
||||
AUDIO_ENABLED);
|
||||
DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id);
|
||||
enable ? AUDIO_ENABLED : 0);
|
||||
}
|
||||
|
||||
static const u32 pin_offsets[7] =
|
||||
@ -323,7 +325,8 @@ int dce6_audio_init(struct radeon_device *rdev)
|
||||
rdev->audio.pin[i].connected = false;
|
||||
rdev->audio.pin[i].offset = pin_offsets[i];
|
||||
rdev->audio.pin[i].id = i;
|
||||
dce6_audio_enable(rdev, &rdev->audio.pin[i], true);
|
||||
/* disable audio. it will be set up later */
|
||||
dce6_audio_enable(rdev, &rdev->audio.pin[i], false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -5475,9 +5475,9 @@ void evergreen_fini(struct radeon_device *rdev)
|
||||
radeon_wb_fini(rdev);
|
||||
radeon_ib_pool_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
evergreen_pcie_gart_fini(rdev);
|
||||
uvd_v1_0_fini(rdev);
|
||||
radeon_uvd_fini(rdev);
|
||||
evergreen_pcie_gart_fini(rdev);
|
||||
r600_vram_scratch_fini(rdev);
|
||||
radeon_gem_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
|
@ -306,6 +306,15 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
|
||||
return;
|
||||
offset = dig->afmt->offset;
|
||||
|
||||
/* disable audio prior to setting up hw */
|
||||
if (ASIC_IS_DCE6(rdev)) {
|
||||
dig->afmt->pin = dce6_audio_get_pin(rdev);
|
||||
dce6_audio_enable(rdev, dig->afmt->pin, false);
|
||||
} else {
|
||||
dig->afmt->pin = r600_audio_get_pin(rdev);
|
||||
r600_audio_enable(rdev, dig->afmt->pin, false);
|
||||
}
|
||||
|
||||
evergreen_audio_set_dto(encoder, mode->clock);
|
||||
|
||||
WREG32(HDMI_VBI_PACKET_CONTROL + offset,
|
||||
@ -409,12 +418,16 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
|
||||
WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);
|
||||
WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001);
|
||||
WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001);
|
||||
|
||||
/* enable audio after to setting up hw */
|
||||
if (ASIC_IS_DCE6(rdev))
|
||||
dce6_audio_enable(rdev, dig->afmt->pin, true);
|
||||
else
|
||||
r600_audio_enable(rdev, dig->afmt->pin, true);
|
||||
}
|
||||
|
||||
void evergreen_hdmi_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;
|
||||
|
||||
@ -427,15 +440,6 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
|
||||
if (!enable && !dig->afmt->enabled)
|
||||
return;
|
||||
|
||||
if (enable) {
|
||||
if (ASIC_IS_DCE6(rdev))
|
||||
dig->afmt->pin = dce6_audio_get_pin(rdev);
|
||||
else
|
||||
dig->afmt->pin = r600_audio_get_pin(rdev);
|
||||
} else {
|
||||
dig->afmt->pin = NULL;
|
||||
}
|
||||
|
||||
dig->afmt->enabled = enable;
|
||||
|
||||
DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",
|
||||
|
@ -142,12 +142,15 @@ void r600_audio_update_hdmi(struct work_struct *work)
|
||||
}
|
||||
|
||||
/* enable the audio stream */
|
||||
static void r600_audio_enable(struct radeon_device *rdev,
|
||||
struct r600_audio_pin *pin,
|
||||
bool enable)
|
||||
void r600_audio_enable(struct radeon_device *rdev,
|
||||
struct r600_audio_pin *pin,
|
||||
bool enable)
|
||||
{
|
||||
u32 value = 0;
|
||||
|
||||
if (!pin)
|
||||
return;
|
||||
|
||||
if (ASIC_IS_DCE4(rdev)) {
|
||||
if (enable) {
|
||||
value |= 0x81000000; /* Required to enable audio */
|
||||
@ -158,7 +161,6 @@ static void r600_audio_enable(struct radeon_device *rdev,
|
||||
WREG32_P(R600_AUDIO_ENABLE,
|
||||
enable ? 0x81000000 : 0x0, ~0x81000000);
|
||||
}
|
||||
DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -178,8 +180,8 @@ int r600_audio_init(struct radeon_device *rdev)
|
||||
rdev->audio.pin[0].status_bits = 0;
|
||||
rdev->audio.pin[0].category_code = 0;
|
||||
rdev->audio.pin[0].id = 0;
|
||||
|
||||
r600_audio_enable(rdev, &rdev->audio.pin[0], true);
|
||||
/* disable audio. it will be set up later */
|
||||
r600_audio_enable(rdev, &rdev->audio.pin[0], false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -329,9 +329,6 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder)
|
||||
u8 *sadb;
|
||||
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) {
|
||||
if (connector->encoder == encoder) {
|
||||
radeon_connector = to_radeon_connector(connector);
|
||||
@ -460,6 +457,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
|
||||
return;
|
||||
offset = dig->afmt->offset;
|
||||
|
||||
/* disable audio prior to setting up hw */
|
||||
dig->afmt->pin = r600_audio_get_pin(rdev);
|
||||
r600_audio_enable(rdev, dig->afmt->pin, false);
|
||||
|
||||
r600_audio_set_dto(encoder, mode->clock);
|
||||
|
||||
WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
|
||||
@ -531,6 +532,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
|
||||
WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);
|
||||
|
||||
r600_hdmi_audio_workaround(encoder);
|
||||
|
||||
/* enable audio after to setting up hw */
|
||||
r600_audio_enable(rdev, dig->afmt->pin, true);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -651,11 +655,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
|
||||
if (!enable && !dig->afmt->enabled)
|
||||
return;
|
||||
|
||||
if (enable)
|
||||
dig->afmt->pin = r600_audio_get_pin(rdev);
|
||||
else
|
||||
dig->afmt->pin = NULL;
|
||||
|
||||
/* Older chipsets require setting HDMI and routing manually */
|
||||
if (!ASIC_IS_DCE3(rdev)) {
|
||||
if (enable)
|
||||
|
@ -2747,6 +2747,12 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
|
||||
void r600_audio_update_hdmi(struct work_struct *work);
|
||||
struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev);
|
||||
struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev);
|
||||
void r600_audio_enable(struct radeon_device *rdev,
|
||||
struct r600_audio_pin *pin,
|
||||
bool enable);
|
||||
void dce6_audio_enable(struct radeon_device *rdev,
|
||||
struct r600_audio_pin *pin,
|
||||
bool enable);
|
||||
|
||||
/*
|
||||
* R600 vram scratch functions
|
||||
|
@ -219,7 +219,8 @@ static int radeon_atpx_verify_interface(struct radeon_atpx *atpx)
|
||||
memcpy(&output, info->buffer.pointer, size);
|
||||
|
||||
/* TODO: check version? */
|
||||
printk("ATPX version %u\n", output.version);
|
||||
printk("ATPX version %u, functions 0x%08x\n",
|
||||
output.version, output.function_bits);
|
||||
|
||||
radeon_atpx_parse_functions(&atpx->functions, output.function_bits);
|
||||
|
||||
|
@ -537,6 +537,10 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
||||
|
||||
radeon_vm_init(rdev, &fpriv->vm);
|
||||
|
||||
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* map the ib pool buffer read only into
|
||||
* virtual address space */
|
||||
bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
|
||||
@ -544,6 +548,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
|
||||
r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
|
||||
RADEON_VM_PAGE_READABLE |
|
||||
RADEON_VM_PAGE_SNOOPED);
|
||||
|
||||
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
|
||||
if (r) {
|
||||
radeon_vm_fini(rdev, &fpriv->vm);
|
||||
kfree(fpriv);
|
||||
|
@ -171,6 +171,8 @@ void radeon_uvd_fini(struct radeon_device *rdev)
|
||||
|
||||
radeon_bo_unref(&rdev->uvd.vcpu_bo);
|
||||
|
||||
radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]);
|
||||
|
||||
release_firmware(rdev->uvd_fw);
|
||||
}
|
||||
|
||||
|
@ -1955,9 +1955,9 @@ void rv770_fini(struct radeon_device *rdev)
|
||||
radeon_wb_fini(rdev);
|
||||
radeon_ib_pool_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
rv770_pcie_gart_fini(rdev);
|
||||
uvd_v1_0_fini(rdev);
|
||||
radeon_uvd_fini(rdev);
|
||||
rv770_pcie_gart_fini(rdev);
|
||||
r600_vram_scratch_fini(rdev);
|
||||
radeon_gem_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
|
Loading…
Reference in New Issue
Block a user