Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Mostly radeon, more fixes for dynamic power management which is is off by default for this release anyways, but there are a large number of testers, so I'd like to keep merging the fixes. Otherwise, radeon UVD fixes affecting suspend/resume regressions, i915 regression fixes, one for your mac mini, ast, mgag200, cirrus ttm fix and one regression fix in the core" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (25 commits) drm: Don't pass negative delta to ktime_sub_ns() drm/radeon: make missing smc ucode non-fatal drm/radeon/dpm: require rlc for dpm drm/radeon/cik: use a mutex to properly lock srbm instanced registers drm/radeon: remove unnecessary unpin drm/radeon: add more UVD CS checking drm/radeon: stop sending invalid UVD destroy msg drm/radeon: only save UVD bo when we have open handles drm/radeon: always program the MC on startup drm/radeon: fix audio dto calculation on DCE3+ (v3) drm/radeon/dpm: disable sclk ss on rv6xx drm/radeon: fix halting UVD drm/radeon/dpm: adjust power state properly for UVD on SI drm/radeon/dpm: fix spread spectrum setup (v2) drm/radeon/dpm: adjust thermal protection requirements drm/radeon: select audio dto based on encoder id for DCE3 drm/radeon: properly handle pm on gpu reset drm/i915: do not disable backlight on vgaswitcheroo switch off drm/i915: Don't call encoder's get_config unless encoder is active drm/i915: avoid brightness overflow when doing scale ...
This commit is contained in:
commit
6a93316661
@ -323,6 +323,7 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
|
|||||||
|
|
||||||
astbo->gem.driver_private = NULL;
|
astbo->gem.driver_private = NULL;
|
||||||
astbo->bo.bdev = &ast->ttm.bdev;
|
astbo->bo.bdev = &ast->ttm.bdev;
|
||||||
|
astbo->bo.bdev->dev_mapping = dev->dev_mapping;
|
||||||
|
|
||||||
ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
|
ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
|
||||||
|
|
||||||
|
@ -328,6 +328,7 @@ int cirrus_bo_create(struct drm_device *dev, int size, int align,
|
|||||||
|
|
||||||
cirrusbo->gem.driver_private = NULL;
|
cirrusbo->gem.driver_private = NULL;
|
||||||
cirrusbo->bo.bdev = &cirrus->ttm.bdev;
|
cirrusbo->bo.bdev = &cirrus->ttm.bdev;
|
||||||
|
cirrusbo->bo.bdev->dev_mapping = dev->dev_mapping;
|
||||||
|
|
||||||
cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
|
cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
|
||||||
|
|
||||||
|
@ -708,6 +708,9 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
|
|||||||
/* Subtract time delta from raw timestamp to get final
|
/* Subtract time delta from raw timestamp to get final
|
||||||
* vblank_time timestamp for end of vblank.
|
* vblank_time timestamp for end of vblank.
|
||||||
*/
|
*/
|
||||||
|
if (delta_ns < 0)
|
||||||
|
etime = ktime_add_ns(etime, -delta_ns);
|
||||||
|
else
|
||||||
etime = ktime_sub_ns(etime, delta_ns);
|
etime = ktime_sub_ns(etime, delta_ns);
|
||||||
*vblank_time = ktime_to_timeval(etime);
|
*vblank_time = ktime_to_timeval(etime);
|
||||||
|
|
||||||
|
@ -1856,10 +1856,16 @@
|
|||||||
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
|
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
|
||||||
|
|
||||||
#define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114)
|
#define PORT_HOTPLUG_STAT (dev_priv->info->display_mmio_offset + 0x61114)
|
||||||
/* HDMI/DP bits are gen4+ */
|
/*
|
||||||
#define PORTB_HOTPLUG_LIVE_STATUS (1 << 29)
|
* HDMI/DP bits are gen4+
|
||||||
|
*
|
||||||
|
* WARNING: Bspec for hpd status bits on gen4 seems to be completely confused.
|
||||||
|
* Please check the detailed lore in the commit message for for experimental
|
||||||
|
* evidence.
|
||||||
|
*/
|
||||||
|
#define PORTD_HOTPLUG_LIVE_STATUS (1 << 29)
|
||||||
#define PORTC_HOTPLUG_LIVE_STATUS (1 << 28)
|
#define PORTC_HOTPLUG_LIVE_STATUS (1 << 28)
|
||||||
#define PORTD_HOTPLUG_LIVE_STATUS (1 << 27)
|
#define PORTB_HOTPLUG_LIVE_STATUS (1 << 27)
|
||||||
#define PORTD_HOTPLUG_INT_STATUS (3 << 21)
|
#define PORTD_HOTPLUG_INT_STATUS (3 << 21)
|
||||||
#define PORTC_HOTPLUG_INT_STATUS (3 << 19)
|
#define PORTC_HOTPLUG_INT_STATUS (3 << 19)
|
||||||
#define PORTB_HOTPLUG_INT_STATUS (3 << 17)
|
#define PORTB_HOTPLUG_INT_STATUS (3 << 17)
|
||||||
|
@ -8269,9 +8269,11 @@ check_crtc_state(struct drm_device *dev)
|
|||||||
|
|
||||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
||||||
base.head) {
|
base.head) {
|
||||||
|
enum pipe pipe;
|
||||||
if (encoder->base.crtc != &crtc->base)
|
if (encoder->base.crtc != &crtc->base)
|
||||||
continue;
|
continue;
|
||||||
if (encoder->get_config)
|
if (encoder->get_config &&
|
||||||
|
encoder->get_hw_state(encoder, &pipe))
|
||||||
encoder->get_config(encoder, &pipe_config);
|
encoder->get_config(encoder, &pipe_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,8 +497,11 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* scale to hardware */
|
/* scale to hardware, but be careful to not overflow */
|
||||||
|
if (freq < max)
|
||||||
level = level * freq / max;
|
level = level * freq / max;
|
||||||
|
else
|
||||||
|
level = freq / max * level;
|
||||||
|
|
||||||
dev_priv->backlight.level = level;
|
dev_priv->backlight.level = level;
|
||||||
if (dev_priv->backlight.device)
|
if (dev_priv->backlight.device)
|
||||||
@ -515,6 +518,17 @@ void intel_panel_disable_backlight(struct drm_device *dev)
|
|||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not disable backlight on the vgaswitcheroo path. When switching
|
||||||
|
* away from i915, the other client may depend on i915 to handle the
|
||||||
|
* backlight. This will leave the backlight on unnecessarily when
|
||||||
|
* another client is not activated.
|
||||||
|
*/
|
||||||
|
if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
|
||||||
|
DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
|
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
|
||||||
|
|
||||||
dev_priv->backlight.enabled = false;
|
dev_priv->backlight.enabled = false;
|
||||||
|
@ -5063,8 +5063,26 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (enable_requested) {
|
if (enable_requested) {
|
||||||
|
unsigned long irqflags;
|
||||||
|
enum pipe p;
|
||||||
|
|
||||||
I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
|
I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
|
||||||
|
POSTING_READ(HSW_PWR_WELL_DRIVER);
|
||||||
DRM_DEBUG_KMS("Requesting to disable the power well\n");
|
DRM_DEBUG_KMS("Requesting to disable the power well\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After this, the registers on the pipes that are part
|
||||||
|
* of the power well will become zero, so we have to
|
||||||
|
* adjust our counters according to that.
|
||||||
|
*
|
||||||
|
* FIXME: Should we do this in general in
|
||||||
|
* drm_vblank_post_modeset?
|
||||||
|
*/
|
||||||
|
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||||
|
for_each_pipe(p)
|
||||||
|
if (p != PIPE_A)
|
||||||
|
dev->last_vblank[p] = 0;
|
||||||
|
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,6 +323,7 @@ int mgag200_bo_create(struct drm_device *dev, int size, int align,
|
|||||||
|
|
||||||
mgabo->gem.driver_private = NULL;
|
mgabo->gem.driver_private = NULL;
|
||||||
mgabo->bo.bdev = &mdev->ttm.bdev;
|
mgabo->bo.bdev = &mdev->ttm.bdev;
|
||||||
|
mgabo->bo.bdev->dev_mapping = dev->dev_mapping;
|
||||||
|
|
||||||
mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
|
mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
|
||||||
|
|
||||||
|
@ -2548,9 +2548,6 @@ int btc_dpm_init(struct radeon_device *rdev)
|
|||||||
{
|
{
|
||||||
struct rv7xx_power_info *pi;
|
struct rv7xx_power_info *pi;
|
||||||
struct evergreen_power_info *eg_pi;
|
struct evergreen_power_info *eg_pi;
|
||||||
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
|
|
||||||
u16 data_offset, size;
|
|
||||||
u8 frev, crev;
|
|
||||||
struct atom_clock_dividers dividers;
|
struct atom_clock_dividers dividers;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -2633,16 +2630,7 @@ int btc_dpm_init(struct radeon_device *rdev)
|
|||||||
eg_pi->vddci_control =
|
eg_pi->vddci_control =
|
||||||
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
|
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
|
||||||
|
|
||||||
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
|
rv770_get_engine_memory_ss(rdev);
|
||||||
&frev, &crev, &data_offset)) {
|
|
||||||
pi->sclk_ss = true;
|
|
||||||
pi->mclk_ss = true;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
} else {
|
|
||||||
pi->sclk_ss = false;
|
|
||||||
pi->mclk_ss = false;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pi->asi = RV770_ASI_DFLT;
|
pi->asi = RV770_ASI_DFLT;
|
||||||
pi->pasi = CYPRESS_HASI_DFLT;
|
pi->pasi = CYPRESS_HASI_DFLT;
|
||||||
@ -2659,8 +2647,7 @@ int btc_dpm_init(struct radeon_device *rdev)
|
|||||||
|
|
||||||
pi->dynamic_pcie_gen2 = true;
|
pi->dynamic_pcie_gen2 = true;
|
||||||
|
|
||||||
if (pi->gfx_clock_gating &&
|
if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
|
||||||
(rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
|
|
||||||
pi->thermal_protection = true;
|
pi->thermal_protection = true;
|
||||||
else
|
else
|
||||||
pi->thermal_protection = false;
|
pi->thermal_protection = false;
|
||||||
|
@ -2587,9 +2587,11 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
|
|||||||
if (rdev->wb.enabled) {
|
if (rdev->wb.enabled) {
|
||||||
rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
|
rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
|
||||||
} else {
|
} else {
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
||||||
rptr = RREG32(CP_HQD_PQ_RPTR);
|
rptr = RREG32(CP_HQD_PQ_RPTR);
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
}
|
}
|
||||||
rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
||||||
|
|
||||||
@ -2604,9 +2606,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
|
|||||||
if (rdev->wb.enabled) {
|
if (rdev->wb.enabled) {
|
||||||
wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
|
wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
|
||||||
} else {
|
} else {
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
|
||||||
wptr = RREG32(CP_HQD_PQ_WPTR);
|
wptr = RREG32(CP_HQD_PQ_WPTR);
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
}
|
}
|
||||||
wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
|
||||||
|
|
||||||
@ -2897,6 +2901,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
|||||||
WREG32(CP_CPF_DEBUG, tmp);
|
WREG32(CP_CPF_DEBUG, tmp);
|
||||||
|
|
||||||
/* init the pipes */
|
/* init the pipes */
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) {
|
for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) {
|
||||||
int me = (i < 4) ? 1 : 2;
|
int me = (i < 4) ? 1 : 2;
|
||||||
int pipe = (i < 4) ? i : (i - 4);
|
int pipe = (i < 4) ? i : (i - 4);
|
||||||
@ -2919,6 +2924,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
|||||||
WREG32(CP_HPD_EOP_CONTROL, tmp);
|
WREG32(CP_HPD_EOP_CONTROL, tmp);
|
||||||
}
|
}
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
|
|
||||||
/* init the queues. Just two for now. */
|
/* init the queues. Just two for now. */
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
@ -2972,6 +2978,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
|||||||
mqd->static_thread_mgmt23[0] = 0xffffffff;
|
mqd->static_thread_mgmt23[0] = 0xffffffff;
|
||||||
mqd->static_thread_mgmt23[1] = 0xffffffff;
|
mqd->static_thread_mgmt23[1] = 0xffffffff;
|
||||||
|
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
cik_srbm_select(rdev, rdev->ring[idx].me,
|
cik_srbm_select(rdev, rdev->ring[idx].me,
|
||||||
rdev->ring[idx].pipe,
|
rdev->ring[idx].pipe,
|
||||||
rdev->ring[idx].queue, 0);
|
rdev->ring[idx].queue, 0);
|
||||||
@ -3099,6 +3106,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
|||||||
WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
|
WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
|
||||||
|
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
|
|
||||||
radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
|
radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
|
||||||
radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
|
radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
|
||||||
@ -4320,6 +4328,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
|
|||||||
|
|
||||||
/* XXX SH_MEM regs */
|
/* XXX SH_MEM regs */
|
||||||
/* where to put LDS, scratch, GPUVM in FSA64 space */
|
/* where to put LDS, scratch, GPUVM in FSA64 space */
|
||||||
|
mutex_lock(&rdev->srbm_mutex);
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
cik_srbm_select(rdev, 0, 0, 0, i);
|
cik_srbm_select(rdev, 0, 0, 0, i);
|
||||||
/* CP and shaders */
|
/* CP and shaders */
|
||||||
@ -4335,6 +4344,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
|
|||||||
/* XXX SDMA RLC - todo */
|
/* XXX SDMA RLC - todo */
|
||||||
}
|
}
|
||||||
cik_srbm_select(rdev, 0, 0, 0, 0);
|
cik_srbm_select(rdev, 0, 0, 0, 0);
|
||||||
|
mutex_unlock(&rdev->srbm_mutex);
|
||||||
|
|
||||||
cik_pcie_gart_tlb_flush(rdev);
|
cik_pcie_gart_tlb_flush(rdev);
|
||||||
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
|
||||||
@ -5954,6 +5964,8 @@ static int cik_startup(struct radeon_device *rdev)
|
|||||||
struct radeon_ring *ring;
|
struct radeon_ring *ring;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
cik_mc_program(rdev);
|
||||||
|
|
||||||
if (rdev->flags & RADEON_IS_IGP) {
|
if (rdev->flags & RADEON_IS_IGP) {
|
||||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
|
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
|
||||||
!rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
|
!rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
|
||||||
@ -5985,7 +5997,6 @@ static int cik_startup(struct radeon_device *rdev)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
cik_mc_program(rdev);
|
|
||||||
r = cik_pcie_gart_enable(rdev);
|
r = cik_pcie_gart_enable(rdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
@ -6194,7 +6205,7 @@ int cik_suspend(struct radeon_device *rdev)
|
|||||||
radeon_vm_manager_fini(rdev);
|
radeon_vm_manager_fini(rdev);
|
||||||
cik_cp_enable(rdev, false);
|
cik_cp_enable(rdev, false);
|
||||||
cik_sdma_enable(rdev, false);
|
cik_sdma_enable(rdev, false);
|
||||||
r600_uvd_rbc_stop(rdev);
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_suspend(rdev);
|
radeon_uvd_suspend(rdev);
|
||||||
cik_irq_suspend(rdev);
|
cik_irq_suspend(rdev);
|
||||||
radeon_wb_disable(rdev);
|
radeon_wb_disable(rdev);
|
||||||
@ -6358,6 +6369,7 @@ void cik_fini(struct radeon_device *rdev)
|
|||||||
radeon_vm_manager_fini(rdev);
|
radeon_vm_manager_fini(rdev);
|
||||||
radeon_ib_pool_fini(rdev);
|
radeon_ib_pool_fini(rdev);
|
||||||
radeon_irq_kms_fini(rdev);
|
radeon_irq_kms_fini(rdev);
|
||||||
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_fini(rdev);
|
radeon_uvd_fini(rdev);
|
||||||
cik_pcie_gart_fini(rdev);
|
cik_pcie_gart_fini(rdev);
|
||||||
r600_vram_scratch_fini(rdev);
|
r600_vram_scratch_fini(rdev);
|
||||||
@ -6978,7 +6990,7 @@ int cik_uvd_resume(struct radeon_device *rdev)
|
|||||||
|
|
||||||
/* programm the VCPU memory controller bits 0-27 */
|
/* programm the VCPU memory controller bits 0-27 */
|
||||||
addr = rdev->uvd.gpu_addr >> 3;
|
addr = rdev->uvd.gpu_addr >> 3;
|
||||||
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
|
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
|
||||||
WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
|
WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
|
||||||
WREG32(UVD_VCPU_CACHE_SIZE0, size);
|
WREG32(UVD_VCPU_CACHE_SIZE0, size);
|
||||||
|
|
||||||
|
@ -2038,9 +2038,6 @@ int cypress_dpm_init(struct radeon_device *rdev)
|
|||||||
{
|
{
|
||||||
struct rv7xx_power_info *pi;
|
struct rv7xx_power_info *pi;
|
||||||
struct evergreen_power_info *eg_pi;
|
struct evergreen_power_info *eg_pi;
|
||||||
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
|
|
||||||
uint16_t data_offset, size;
|
|
||||||
uint8_t frev, crev;
|
|
||||||
struct atom_clock_dividers dividers;
|
struct atom_clock_dividers dividers;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -2092,16 +2089,7 @@ int cypress_dpm_init(struct radeon_device *rdev)
|
|||||||
eg_pi->vddci_control =
|
eg_pi->vddci_control =
|
||||||
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
|
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
|
||||||
|
|
||||||
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
|
rv770_get_engine_memory_ss(rdev);
|
||||||
&frev, &crev, &data_offset)) {
|
|
||||||
pi->sclk_ss = true;
|
|
||||||
pi->mclk_ss = true;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
} else {
|
|
||||||
pi->sclk_ss = false;
|
|
||||||
pi->mclk_ss = false;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pi->asi = RV770_ASI_DFLT;
|
pi->asi = RV770_ASI_DFLT;
|
||||||
pi->pasi = CYPRESS_HASI_DFLT;
|
pi->pasi = CYPRESS_HASI_DFLT;
|
||||||
@ -2122,8 +2110,7 @@ int cypress_dpm_init(struct radeon_device *rdev)
|
|||||||
|
|
||||||
pi->dynamic_pcie_gen2 = true;
|
pi->dynamic_pcie_gen2 = true;
|
||||||
|
|
||||||
if (pi->gfx_clock_gating &&
|
if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
|
||||||
(rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
|
|
||||||
pi->thermal_protection = true;
|
pi->thermal_protection = true;
|
||||||
else
|
else
|
||||||
pi->thermal_protection = false;
|
pi->thermal_protection = false;
|
||||||
|
@ -5106,6 +5106,8 @@ static int evergreen_startup(struct radeon_device *rdev)
|
|||||||
/* enable aspm */
|
/* enable aspm */
|
||||||
evergreen_program_aspm(rdev);
|
evergreen_program_aspm(rdev);
|
||||||
|
|
||||||
|
evergreen_mc_program(rdev);
|
||||||
|
|
||||||
if (ASIC_IS_DCE5(rdev)) {
|
if (ASIC_IS_DCE5(rdev)) {
|
||||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
|
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
|
||||||
r = ni_init_microcode(rdev);
|
r = ni_init_microcode(rdev);
|
||||||
@ -5133,7 +5135,6 @@ static int evergreen_startup(struct radeon_device *rdev)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
evergreen_mc_program(rdev);
|
|
||||||
if (rdev->flags & RADEON_IS_AGP) {
|
if (rdev->flags & RADEON_IS_AGP) {
|
||||||
evergreen_agp_enable(rdev);
|
evergreen_agp_enable(rdev);
|
||||||
} else {
|
} else {
|
||||||
@ -5291,10 +5292,10 @@ int evergreen_resume(struct radeon_device *rdev)
|
|||||||
int evergreen_suspend(struct radeon_device *rdev)
|
int evergreen_suspend(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
r600_audio_fini(rdev);
|
r600_audio_fini(rdev);
|
||||||
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_suspend(rdev);
|
radeon_uvd_suspend(rdev);
|
||||||
r700_cp_stop(rdev);
|
r700_cp_stop(rdev);
|
||||||
r600_dma_stop(rdev);
|
r600_dma_stop(rdev);
|
||||||
r600_uvd_rbc_stop(rdev);
|
|
||||||
evergreen_irq_suspend(rdev);
|
evergreen_irq_suspend(rdev);
|
||||||
radeon_wb_disable(rdev);
|
radeon_wb_disable(rdev);
|
||||||
evergreen_pcie_gart_disable(rdev);
|
evergreen_pcie_gart_disable(rdev);
|
||||||
@ -5429,6 +5430,7 @@ void evergreen_fini(struct radeon_device *rdev)
|
|||||||
radeon_ib_pool_fini(rdev);
|
radeon_ib_pool_fini(rdev);
|
||||||
radeon_irq_kms_fini(rdev);
|
radeon_irq_kms_fini(rdev);
|
||||||
evergreen_pcie_gart_fini(rdev);
|
evergreen_pcie_gart_fini(rdev);
|
||||||
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_fini(rdev);
|
radeon_uvd_fini(rdev);
|
||||||
r600_vram_scratch_fini(rdev);
|
r600_vram_scratch_fini(rdev);
|
||||||
radeon_gem_fini(rdev);
|
radeon_gem_fini(rdev);
|
||||||
|
@ -148,18 +148,40 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
|
|||||||
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
||||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
||||||
u32 base_rate = 24000;
|
u32 base_rate = 24000;
|
||||||
|
u32 max_ratio = clock / base_rate;
|
||||||
|
u32 dto_phase;
|
||||||
|
u32 dto_modulo = clock;
|
||||||
|
u32 wallclock_ratio;
|
||||||
|
u32 dto_cntl;
|
||||||
|
|
||||||
if (!dig || !dig->afmt)
|
if (!dig || !dig->afmt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (max_ratio >= 8) {
|
||||||
|
dto_phase = 192 * 1000;
|
||||||
|
wallclock_ratio = 3;
|
||||||
|
} else if (max_ratio >= 4) {
|
||||||
|
dto_phase = 96 * 1000;
|
||||||
|
wallclock_ratio = 2;
|
||||||
|
} else if (max_ratio >= 2) {
|
||||||
|
dto_phase = 48 * 1000;
|
||||||
|
wallclock_ratio = 1;
|
||||||
|
} else {
|
||||||
|
dto_phase = 24 * 1000;
|
||||||
|
wallclock_ratio = 0;
|
||||||
|
}
|
||||||
|
dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||||
|
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||||
|
WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
|
||||||
|
|
||||||
/* XXX two dtos; generally use dto0 for hdmi */
|
/* XXX two dtos; generally use dto0 for hdmi */
|
||||||
/* 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_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
|
WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
|
||||||
WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
|
WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
|
||||||
WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
|
WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,6 +497,9 @@
|
|||||||
#define DCCG_AUDIO_DTO0_MODULE 0x05b4
|
#define DCCG_AUDIO_DTO0_MODULE 0x05b4
|
||||||
#define DCCG_AUDIO_DTO0_LOAD 0x05b8
|
#define DCCG_AUDIO_DTO0_LOAD 0x05b8
|
||||||
#define DCCG_AUDIO_DTO0_CNTL 0x05bc
|
#define DCCG_AUDIO_DTO0_CNTL 0x05bc
|
||||||
|
# define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0)
|
||||||
|
# define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7
|
||||||
|
# define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0
|
||||||
|
|
||||||
#define DCCG_AUDIO_DTO1_PHASE 0x05c0
|
#define DCCG_AUDIO_DTO1_PHASE 0x05c0
|
||||||
#define DCCG_AUDIO_DTO1_MODULE 0x05c4
|
#define DCCG_AUDIO_DTO1_MODULE 0x05c4
|
||||||
|
@ -794,9 +794,13 @@ int ni_init_microcode(struct radeon_device *rdev)
|
|||||||
if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
|
if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
|
||||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
|
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
|
||||||
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
|
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
|
||||||
if (err)
|
if (err) {
|
||||||
goto out;
|
printk(KERN_ERR
|
||||||
if (rdev->smc_fw->size != smc_req_size) {
|
"smc: error loading firmware \"%s\"\n",
|
||||||
|
fw_name);
|
||||||
|
release_firmware(rdev->smc_fw);
|
||||||
|
rdev->smc_fw = NULL;
|
||||||
|
} 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",
|
||||||
rdev->mc_fw->size, fw_name);
|
rdev->mc_fw->size, fw_name);
|
||||||
@ -2079,6 +2083,8 @@ static int cayman_startup(struct radeon_device *rdev)
|
|||||||
/* enable aspm */
|
/* enable aspm */
|
||||||
evergreen_program_aspm(rdev);
|
evergreen_program_aspm(rdev);
|
||||||
|
|
||||||
|
evergreen_mc_program(rdev);
|
||||||
|
|
||||||
if (rdev->flags & RADEON_IS_IGP) {
|
if (rdev->flags & RADEON_IS_IGP) {
|
||||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
||||||
r = ni_init_microcode(rdev);
|
r = ni_init_microcode(rdev);
|
||||||
@ -2107,7 +2113,6 @@ static int cayman_startup(struct radeon_device *rdev)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
evergreen_mc_program(rdev);
|
|
||||||
r = cayman_pcie_gart_enable(rdev);
|
r = cayman_pcie_gart_enable(rdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
@ -2286,7 +2291,7 @@ int cayman_suspend(struct radeon_device *rdev)
|
|||||||
radeon_vm_manager_fini(rdev);
|
radeon_vm_manager_fini(rdev);
|
||||||
cayman_cp_enable(rdev, false);
|
cayman_cp_enable(rdev, false);
|
||||||
cayman_dma_stop(rdev);
|
cayman_dma_stop(rdev);
|
||||||
r600_uvd_rbc_stop(rdev);
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_suspend(rdev);
|
radeon_uvd_suspend(rdev);
|
||||||
evergreen_irq_suspend(rdev);
|
evergreen_irq_suspend(rdev);
|
||||||
radeon_wb_disable(rdev);
|
radeon_wb_disable(rdev);
|
||||||
@ -2418,6 +2423,7 @@ void cayman_fini(struct radeon_device *rdev)
|
|||||||
radeon_vm_manager_fini(rdev);
|
radeon_vm_manager_fini(rdev);
|
||||||
radeon_ib_pool_fini(rdev);
|
radeon_ib_pool_fini(rdev);
|
||||||
radeon_irq_kms_fini(rdev);
|
radeon_irq_kms_fini(rdev);
|
||||||
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_fini(rdev);
|
radeon_uvd_fini(rdev);
|
||||||
cayman_pcie_gart_fini(rdev);
|
cayman_pcie_gart_fini(rdev);
|
||||||
r600_vram_scratch_fini(rdev);
|
r600_vram_scratch_fini(rdev);
|
||||||
|
@ -4067,9 +4067,6 @@ int ni_dpm_init(struct radeon_device *rdev)
|
|||||||
struct rv7xx_power_info *pi;
|
struct rv7xx_power_info *pi;
|
||||||
struct evergreen_power_info *eg_pi;
|
struct evergreen_power_info *eg_pi;
|
||||||
struct ni_power_info *ni_pi;
|
struct ni_power_info *ni_pi;
|
||||||
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
|
|
||||||
u16 data_offset, size;
|
|
||||||
u8 frev, crev;
|
|
||||||
struct atom_clock_dividers dividers;
|
struct atom_clock_dividers dividers;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -4162,16 +4159,7 @@ int ni_dpm_init(struct radeon_device *rdev)
|
|||||||
eg_pi->vddci_control =
|
eg_pi->vddci_control =
|
||||||
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
|
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
|
||||||
|
|
||||||
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
|
rv770_get_engine_memory_ss(rdev);
|
||||||
&frev, &crev, &data_offset)) {
|
|
||||||
pi->sclk_ss = true;
|
|
||||||
pi->mclk_ss = true;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
} else {
|
|
||||||
pi->sclk_ss = false;
|
|
||||||
pi->mclk_ss = false;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pi->asi = RV770_ASI_DFLT;
|
pi->asi = RV770_ASI_DFLT;
|
||||||
pi->pasi = CYPRESS_HASI_DFLT;
|
pi->pasi = CYPRESS_HASI_DFLT;
|
||||||
@ -4188,8 +4176,7 @@ int ni_dpm_init(struct radeon_device *rdev)
|
|||||||
|
|
||||||
pi->dynamic_pcie_gen2 = true;
|
pi->dynamic_pcie_gen2 = true;
|
||||||
|
|
||||||
if (pi->gfx_clock_gating &&
|
if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
|
||||||
(rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
|
|
||||||
pi->thermal_protection = true;
|
pi->thermal_protection = true;
|
||||||
else
|
else
|
||||||
pi->thermal_protection = false;
|
pi->thermal_protection = false;
|
||||||
|
@ -2299,9 +2299,13 @@ int r600_init_microcode(struct radeon_device *rdev)
|
|||||||
if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) {
|
if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) {
|
||||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name);
|
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name);
|
||||||
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
|
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
|
||||||
if (err)
|
if (err) {
|
||||||
goto out;
|
printk(KERN_ERR
|
||||||
if (rdev->smc_fw->size != smc_req_size) {
|
"smc: error loading firmware \"%s\"\n",
|
||||||
|
fw_name);
|
||||||
|
release_firmware(rdev->smc_fw);
|
||||||
|
rdev->smc_fw = NULL;
|
||||||
|
} 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",
|
||||||
rdev->smc_fw->size, fw_name);
|
rdev->smc_fw->size, fw_name);
|
||||||
@ -2697,12 +2701,29 @@ int r600_uvd_rbc_start(struct radeon_device *rdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void r600_uvd_rbc_stop(struct radeon_device *rdev)
|
void r600_uvd_stop(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
|
struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
|
||||||
|
|
||||||
/* force RBC into idle state */
|
/* force RBC into idle state */
|
||||||
WREG32(UVD_RBC_RB_CNTL, 0x11010101);
|
WREG32(UVD_RBC_RB_CNTL, 0x11010101);
|
||||||
|
|
||||||
|
/* Stall UMC and register bus before resetting VCPU */
|
||||||
|
WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
|
||||||
|
WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
/* put VCPU into reset */
|
||||||
|
WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
|
||||||
|
mdelay(5);
|
||||||
|
|
||||||
|
/* disable VCPU clock */
|
||||||
|
WREG32(UVD_VCPU_CNTL, 0x0);
|
||||||
|
|
||||||
|
/* Unstall UMC and register bus */
|
||||||
|
WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
|
||||||
|
WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
|
||||||
|
|
||||||
ring->ready = false;
|
ring->ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2722,6 +2743,11 @@ int r600_uvd_init(struct radeon_device *rdev)
|
|||||||
/* disable interupt */
|
/* disable interupt */
|
||||||
WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
|
WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
|
||||||
|
|
||||||
|
/* Stall UMC and register bus before resetting VCPU */
|
||||||
|
WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
|
||||||
|
WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
/* put LMI, VCPU, RBC etc... into reset */
|
/* put LMI, VCPU, RBC etc... into reset */
|
||||||
WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
|
WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
|
||||||
LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
|
LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
|
||||||
@ -2751,10 +2777,6 @@ int r600_uvd_init(struct radeon_device *rdev)
|
|||||||
WREG32(UVD_MPC_SET_ALU, 0);
|
WREG32(UVD_MPC_SET_ALU, 0);
|
||||||
WREG32(UVD_MPC_SET_MUX, 0x88);
|
WREG32(UVD_MPC_SET_MUX, 0x88);
|
||||||
|
|
||||||
/* Stall UMC */
|
|
||||||
WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
|
|
||||||
WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
|
|
||||||
|
|
||||||
/* take all subblocks out of reset, except VCPU */
|
/* take all subblocks out of reset, except VCPU */
|
||||||
WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
|
WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
|
||||||
mdelay(5);
|
mdelay(5);
|
||||||
@ -3312,6 +3334,8 @@ static int r600_startup(struct radeon_device *rdev)
|
|||||||
/* enable pcie gen2 link */
|
/* enable pcie gen2 link */
|
||||||
r600_pcie_gen2_enable(rdev);
|
r600_pcie_gen2_enable(rdev);
|
||||||
|
|
||||||
|
r600_mc_program(rdev);
|
||||||
|
|
||||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
||||||
r = r600_init_microcode(rdev);
|
r = r600_init_microcode(rdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
@ -3324,7 +3348,6 @@ static int r600_startup(struct radeon_device *rdev)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r600_mc_program(rdev);
|
|
||||||
if (rdev->flags & RADEON_IS_AGP) {
|
if (rdev->flags & RADEON_IS_AGP) {
|
||||||
r600_agp_enable(rdev);
|
r600_agp_enable(rdev);
|
||||||
} else {
|
} else {
|
||||||
|
@ -226,10 +226,29 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
|
|||||||
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;
|
||||||
u32 base_rate = 24000;
|
u32 base_rate = 24000;
|
||||||
|
u32 max_ratio = clock / base_rate;
|
||||||
|
u32 dto_phase;
|
||||||
|
u32 dto_modulo = clock;
|
||||||
|
u32 wallclock_ratio;
|
||||||
|
u32 dto_cntl;
|
||||||
|
|
||||||
if (!dig || !dig->afmt)
|
if (!dig || !dig->afmt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (max_ratio >= 8) {
|
||||||
|
dto_phase = 192 * 1000;
|
||||||
|
wallclock_ratio = 3;
|
||||||
|
} else if (max_ratio >= 4) {
|
||||||
|
dto_phase = 96 * 1000;
|
||||||
|
wallclock_ratio = 2;
|
||||||
|
} else if (max_ratio >= 2) {
|
||||||
|
dto_phase = 48 * 1000;
|
||||||
|
wallclock_ratio = 1;
|
||||||
|
} else {
|
||||||
|
dto_phase = 24 * 1000;
|
||||||
|
wallclock_ratio = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
|
/* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
|
||||||
* doesn't matter which one you use. Just use the first one.
|
* doesn't matter which one you use. Just use the first one.
|
||||||
*/
|
*/
|
||||||
@ -242,9 +261,21 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
|
|||||||
/* according to the reg specs, this should DCE3.2 only, but in
|
/* according to the reg specs, this should DCE3.2 only, but in
|
||||||
* practice it seems to cover DCE3.0 as well.
|
* practice it seems to cover DCE3.0 as well.
|
||||||
*/
|
*/
|
||||||
WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
|
if (dig->dig_encoder == 0) {
|
||||||
WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
|
dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||||
|
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||||
|
WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
|
||||||
|
WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
|
||||||
|
WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
|
||||||
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
|
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
|
||||||
|
} else {
|
||||||
|
dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||||
|
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||||
|
WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl);
|
||||||
|
WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase);
|
||||||
|
WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo);
|
||||||
|
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* according to the reg specs, this should be DCE2.0 and DCE3.0 */
|
/* according to the reg specs, this should be DCE2.0 and DCE3.0 */
|
||||||
WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
|
WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
|
||||||
|
@ -933,6 +933,9 @@
|
|||||||
#define DCCG_AUDIO_DTO0_LOAD 0x051c
|
#define DCCG_AUDIO_DTO0_LOAD 0x051c
|
||||||
# define DTO_LOAD (1 << 31)
|
# define DTO_LOAD (1 << 31)
|
||||||
#define DCCG_AUDIO_DTO0_CNTL 0x0520
|
#define DCCG_AUDIO_DTO0_CNTL 0x0520
|
||||||
|
# define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0)
|
||||||
|
# define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7
|
||||||
|
# define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0
|
||||||
|
|
||||||
#define DCCG_AUDIO_DTO1_PHASE 0x0524
|
#define DCCG_AUDIO_DTO1_PHASE 0x0524
|
||||||
#define DCCG_AUDIO_DTO1_MODULE 0x0528
|
#define DCCG_AUDIO_DTO1_MODULE 0x0528
|
||||||
|
@ -1468,7 +1468,6 @@ struct radeon_uvd {
|
|||||||
void *cpu_addr;
|
void *cpu_addr;
|
||||||
uint64_t gpu_addr;
|
uint64_t gpu_addr;
|
||||||
void *saved_bo;
|
void *saved_bo;
|
||||||
unsigned fw_size;
|
|
||||||
atomic_t handles[RADEON_MAX_UVD_HANDLES];
|
atomic_t handles[RADEON_MAX_UVD_HANDLES];
|
||||||
struct drm_file *filp[RADEON_MAX_UVD_HANDLES];
|
struct drm_file *filp[RADEON_MAX_UVD_HANDLES];
|
||||||
struct delayed_work idle_work;
|
struct delayed_work idle_work;
|
||||||
@ -2066,6 +2065,7 @@ struct radeon_device {
|
|||||||
const struct firmware *mec_fw; /* CIK MEC firmware */
|
const struct firmware *mec_fw; /* CIK MEC firmware */
|
||||||
const struct firmware *sdma_fw; /* CIK SDMA firmware */
|
const struct firmware *sdma_fw; /* CIK SDMA firmware */
|
||||||
const struct firmware *smc_fw; /* SMC firmware */
|
const struct firmware *smc_fw; /* SMC firmware */
|
||||||
|
const struct firmware *uvd_fw; /* UVD firmware */
|
||||||
struct r600_blit r600_blit;
|
struct r600_blit r600_blit;
|
||||||
struct r600_vram_scratch vram_scratch;
|
struct r600_vram_scratch vram_scratch;
|
||||||
int msi_enabled; /* msi enabled */
|
int msi_enabled; /* msi enabled */
|
||||||
@ -2095,6 +2095,8 @@ struct radeon_device {
|
|||||||
/* ACPI interface */
|
/* ACPI interface */
|
||||||
struct radeon_atif atif;
|
struct radeon_atif atif;
|
||||||
struct radeon_atcs atcs;
|
struct radeon_atcs atcs;
|
||||||
|
/* srbm instance registers */
|
||||||
|
struct mutex srbm_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
int radeon_device_init(struct radeon_device *rdev,
|
int radeon_device_init(struct radeon_device *rdev,
|
||||||
|
@ -441,7 +441,7 @@ void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rde
|
|||||||
/* uvd */
|
/* uvd */
|
||||||
int r600_uvd_init(struct radeon_device *rdev);
|
int r600_uvd_init(struct radeon_device *rdev);
|
||||||
int r600_uvd_rbc_start(struct radeon_device *rdev);
|
int r600_uvd_rbc_start(struct radeon_device *rdev);
|
||||||
void r600_uvd_rbc_stop(struct radeon_device *rdev);
|
void r600_uvd_stop(struct radeon_device *rdev);
|
||||||
int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
|
int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
|
||||||
void r600_uvd_fence_emit(struct radeon_device *rdev,
|
void r600_uvd_fence_emit(struct radeon_device *rdev,
|
||||||
struct radeon_fence *fence);
|
struct radeon_fence *fence);
|
||||||
|
@ -1163,6 +1163,7 @@ int radeon_device_init(struct radeon_device *rdev,
|
|||||||
mutex_init(&rdev->gem.mutex);
|
mutex_init(&rdev->gem.mutex);
|
||||||
mutex_init(&rdev->pm.mutex);
|
mutex_init(&rdev->pm.mutex);
|
||||||
mutex_init(&rdev->gpu_clock_mutex);
|
mutex_init(&rdev->gpu_clock_mutex);
|
||||||
|
mutex_init(&rdev->srbm_mutex);
|
||||||
init_rwsem(&rdev->pm.mclk_lock);
|
init_rwsem(&rdev->pm.mclk_lock);
|
||||||
init_rwsem(&rdev->exclusive_lock);
|
init_rwsem(&rdev->exclusive_lock);
|
||||||
init_waitqueue_head(&rdev->irq.vblank_queue);
|
init_waitqueue_head(&rdev->irq.vblank_queue);
|
||||||
@ -1519,6 +1520,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)
|
|||||||
radeon_save_bios_scratch_regs(rdev);
|
radeon_save_bios_scratch_regs(rdev);
|
||||||
/* block TTM */
|
/* block TTM */
|
||||||
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
|
resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
|
||||||
|
radeon_pm_suspend(rdev);
|
||||||
radeon_suspend(rdev);
|
radeon_suspend(rdev);
|
||||||
|
|
||||||
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
|
for (i = 0; i < RADEON_NUM_RINGS; ++i) {
|
||||||
@ -1564,6 +1566,7 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
radeon_pm_resume(rdev);
|
||||||
drm_helper_resume_force_mode(rdev->ddev);
|
drm_helper_resume_force_mode(rdev->ddev);
|
||||||
|
|
||||||
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
|
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
|
||||||
|
@ -782,7 +782,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* put fence directly behind firmware */
|
/* put fence directly behind firmware */
|
||||||
index = ALIGN(rdev->uvd.fw_size, 8);
|
index = ALIGN(rdev->uvd_fw->size, 8);
|
||||||
rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
|
rdev->fence_drv[ring].cpu_addr = rdev->uvd.cpu_addr + index;
|
||||||
rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
|
rdev->fence_drv[ring].gpu_addr = rdev->uvd.gpu_addr + index;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,6 @@ void radeon_gart_table_vram_free(struct radeon_device *rdev)
|
|||||||
if (rdev->gart.robj == NULL) {
|
if (rdev->gart.robj == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
radeon_gart_table_vram_unpin(rdev);
|
|
||||||
radeon_bo_unref(&rdev->gart.robj);
|
radeon_bo_unref(&rdev->gart.robj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,7 +1176,14 @@ int radeon_pm_init(struct radeon_device *rdev)
|
|||||||
case CHIP_VERDE:
|
case CHIP_VERDE:
|
||||||
case CHIP_OLAND:
|
case CHIP_OLAND:
|
||||||
case CHIP_HAINAN:
|
case CHIP_HAINAN:
|
||||||
if (radeon_dpm == 1)
|
/* DPM requires the RLC, RV770+ dGPU requires SMC */
|
||||||
|
if (!rdev->rlc_fw)
|
||||||
|
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
||||||
|
else if ((rdev->family >= CHIP_RV770) &&
|
||||||
|
(!(rdev->flags & RADEON_IS_IGP)) &&
|
||||||
|
(!rdev->smc_fw))
|
||||||
|
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
||||||
|
else if (radeon_dpm == 1)
|
||||||
rdev->pm.pm_method = PM_METHOD_DPM;
|
rdev->pm.pm_method = PM_METHOD_DPM;
|
||||||
else
|
else
|
||||||
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
rdev->pm.pm_method = PM_METHOD_PROFILE;
|
||||||
|
@ -56,7 +56,6 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work);
|
|||||||
|
|
||||||
int radeon_uvd_init(struct radeon_device *rdev)
|
int radeon_uvd_init(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
const struct firmware *fw;
|
|
||||||
unsigned long bo_size;
|
unsigned long bo_size;
|
||||||
const char *fw_name;
|
const char *fw_name;
|
||||||
int i, r;
|
int i, r;
|
||||||
@ -105,14 +104,14 @@ int radeon_uvd_init(struct radeon_device *rdev)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = request_firmware(&fw, fw_name, rdev->dev);
|
r = request_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
|
dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
|
||||||
fw_name);
|
fw_name);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bo_size = RADEON_GPU_PAGE_ALIGN(fw->size + 8) +
|
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
|
||||||
RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
|
RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
|
||||||
r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
|
r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
|
||||||
RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
|
RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
|
||||||
@ -145,12 +144,6 @@ int radeon_uvd_init(struct radeon_device *rdev)
|
|||||||
|
|
||||||
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
|
radeon_bo_unreserve(rdev->uvd.vcpu_bo);
|
||||||
|
|
||||||
rdev->uvd.fw_size = fw->size;
|
|
||||||
memset(rdev->uvd.cpu_addr, 0, bo_size);
|
|
||||||
memcpy(rdev->uvd.cpu_addr, fw->data, fw->size);
|
|
||||||
|
|
||||||
release_firmware(fw);
|
|
||||||
|
|
||||||
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
|
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
|
||||||
atomic_set(&rdev->uvd.handles[i], 0);
|
atomic_set(&rdev->uvd.handles[i], 0);
|
||||||
rdev->uvd.filp[i] = NULL;
|
rdev->uvd.filp[i] = NULL;
|
||||||
@ -174,33 +167,60 @@ void radeon_uvd_fini(struct radeon_device *rdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
radeon_bo_unref(&rdev->uvd.vcpu_bo);
|
radeon_bo_unref(&rdev->uvd.vcpu_bo);
|
||||||
|
|
||||||
|
release_firmware(rdev->uvd_fw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int radeon_uvd_suspend(struct radeon_device *rdev)
|
int radeon_uvd_suspend(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
void *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (rdev->uvd.vcpu_bo == NULL)
|
if (rdev->uvd.vcpu_bo == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
|
||||||
|
if (atomic_read(&rdev->uvd.handles[i]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == RADEON_MAX_UVD_HANDLES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
size = radeon_bo_size(rdev->uvd.vcpu_bo);
|
size = radeon_bo_size(rdev->uvd.vcpu_bo);
|
||||||
|
size -= rdev->uvd_fw->size;
|
||||||
|
|
||||||
|
ptr = rdev->uvd.cpu_addr;
|
||||||
|
ptr += rdev->uvd_fw->size;
|
||||||
|
|
||||||
rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
|
rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
|
||||||
memcpy(rdev->uvd.saved_bo, rdev->uvd.cpu_addr, size);
|
memcpy(rdev->uvd.saved_bo, ptr, size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int radeon_uvd_resume(struct radeon_device *rdev)
|
int radeon_uvd_resume(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
|
unsigned size;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
if (rdev->uvd.vcpu_bo == NULL)
|
if (rdev->uvd.vcpu_bo == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
|
||||||
|
|
||||||
|
size = radeon_bo_size(rdev->uvd.vcpu_bo);
|
||||||
|
size -= rdev->uvd_fw->size;
|
||||||
|
|
||||||
|
ptr = rdev->uvd.cpu_addr;
|
||||||
|
ptr += rdev->uvd_fw->size;
|
||||||
|
|
||||||
if (rdev->uvd.saved_bo != NULL) {
|
if (rdev->uvd.saved_bo != NULL) {
|
||||||
unsigned size = radeon_bo_size(rdev->uvd.vcpu_bo);
|
memcpy(ptr, rdev->uvd.saved_bo, size);
|
||||||
memcpy(rdev->uvd.cpu_addr, rdev->uvd.saved_bo, size);
|
|
||||||
kfree(rdev->uvd.saved_bo);
|
kfree(rdev->uvd.saved_bo);
|
||||||
rdev->uvd.saved_bo = NULL;
|
rdev->uvd.saved_bo = NULL;
|
||||||
}
|
} else
|
||||||
|
memset(ptr, 0, size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -215,8 +235,8 @@ void radeon_uvd_free_handles(struct radeon_device *rdev, struct drm_file *filp)
|
|||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
|
for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
|
||||||
if (rdev->uvd.filp[i] == filp) {
|
|
||||||
uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
|
uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
|
||||||
|
if (handle != 0 && rdev->uvd.filp[i] == filp) {
|
||||||
struct radeon_fence *fence;
|
struct radeon_fence *fence;
|
||||||
|
|
||||||
r = radeon_uvd_get_destroy_msg(rdev,
|
r = radeon_uvd_get_destroy_msg(rdev,
|
||||||
@ -337,8 +357,10 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = radeon_bo_kmap(bo, &ptr);
|
r = radeon_bo_kmap(bo, &ptr);
|
||||||
if (r)
|
if (r) {
|
||||||
|
DRM_ERROR("Failed mapping the UVD message (%d)!\n", r);
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
msg = ptr + offset;
|
msg = ptr + offset;
|
||||||
|
|
||||||
@ -364,8 +386,14 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
|
|||||||
radeon_bo_kunmap(bo);
|
radeon_bo_kunmap(bo);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
/* it's a create msg, no special handling needed */
|
|
||||||
radeon_bo_kunmap(bo);
|
radeon_bo_kunmap(bo);
|
||||||
|
|
||||||
|
if (msg_type != 0) {
|
||||||
|
DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it's a create msg, no special handling needed */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create or decode, validate the handle */
|
/* create or decode, validate the handle */
|
||||||
@ -388,7 +416,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
|
|||||||
|
|
||||||
static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
|
static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
|
||||||
int data0, int data1,
|
int data0, int data1,
|
||||||
unsigned buf_sizes[])
|
unsigned buf_sizes[], bool *has_msg_cmd)
|
||||||
{
|
{
|
||||||
struct radeon_cs_chunk *relocs_chunk;
|
struct radeon_cs_chunk *relocs_chunk;
|
||||||
struct radeon_cs_reloc *reloc;
|
struct radeon_cs_reloc *reloc;
|
||||||
@ -417,7 +445,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
|
|||||||
|
|
||||||
if (cmd < 0x4) {
|
if (cmd < 0x4) {
|
||||||
if ((end - start) < buf_sizes[cmd]) {
|
if ((end - start) < buf_sizes[cmd]) {
|
||||||
DRM_ERROR("buffer to small (%d / %d)!\n",
|
DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
|
||||||
(unsigned)(end - start), buf_sizes[cmd]);
|
(unsigned)(end - start), buf_sizes[cmd]);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -442,9 +470,17 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == 0) {
|
if (cmd == 0) {
|
||||||
|
if (*has_msg_cmd) {
|
||||||
|
DRM_ERROR("More than one message in a UVD-IB!\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
*has_msg_cmd = true;
|
||||||
r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes);
|
r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
} else if (!*has_msg_cmd) {
|
||||||
|
DRM_ERROR("Message needed before other commands are send!\n");
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -453,7 +489,8 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
|
|||||||
static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
|
static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
|
||||||
struct radeon_cs_packet *pkt,
|
struct radeon_cs_packet *pkt,
|
||||||
int *data0, int *data1,
|
int *data0, int *data1,
|
||||||
unsigned buf_sizes[])
|
unsigned buf_sizes[],
|
||||||
|
bool *has_msg_cmd)
|
||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
@ -467,7 +504,8 @@ static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
|
|||||||
*data1 = p->idx;
|
*data1 = p->idx;
|
||||||
break;
|
break;
|
||||||
case UVD_GPCOM_VCPU_CMD:
|
case UVD_GPCOM_VCPU_CMD:
|
||||||
r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes);
|
r = radeon_uvd_cs_reloc(p, *data0, *data1,
|
||||||
|
buf_sizes, has_msg_cmd);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
@ -488,6 +526,9 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
|
|||||||
struct radeon_cs_packet pkt;
|
struct radeon_cs_packet pkt;
|
||||||
int r, data0 = 0, data1 = 0;
|
int r, data0 = 0, data1 = 0;
|
||||||
|
|
||||||
|
/* does the IB has a msg command */
|
||||||
|
bool has_msg_cmd = false;
|
||||||
|
|
||||||
/* minimum buffer sizes */
|
/* minimum buffer sizes */
|
||||||
unsigned buf_sizes[] = {
|
unsigned buf_sizes[] = {
|
||||||
[0x00000000] = 2048,
|
[0x00000000] = 2048,
|
||||||
@ -514,8 +555,8 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
|
|||||||
return r;
|
return r;
|
||||||
switch (pkt.type) {
|
switch (pkt.type) {
|
||||||
case RADEON_PACKET_TYPE0:
|
case RADEON_PACKET_TYPE0:
|
||||||
r = radeon_uvd_cs_reg(p, &pkt, &data0,
|
r = radeon_uvd_cs_reg(p, &pkt, &data0, &data1,
|
||||||
&data1, buf_sizes);
|
buf_sizes, &has_msg_cmd);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
@ -527,6 +568,12 @@ int radeon_uvd_cs_parse(struct radeon_cs_parser *p)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
} while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
|
} while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
|
||||||
|
|
||||||
|
if (!has_msg_cmd) {
|
||||||
|
DRM_ERROR("UVD-IBs need a msg command!\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1944,9 +1944,7 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev)
|
|||||||
|
|
||||||
int rv6xx_dpm_init(struct radeon_device *rdev)
|
int rv6xx_dpm_init(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
|
struct radeon_atom_ss ss;
|
||||||
uint16_t data_offset, size;
|
|
||||||
uint8_t frev, crev;
|
|
||||||
struct atom_clock_dividers dividers;
|
struct atom_clock_dividers dividers;
|
||||||
struct rv6xx_power_info *pi;
|
struct rv6xx_power_info *pi;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1989,16 +1987,18 @@ int rv6xx_dpm_init(struct radeon_device *rdev)
|
|||||||
|
|
||||||
pi->gfx_clock_gating = true;
|
pi->gfx_clock_gating = true;
|
||||||
|
|
||||||
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
|
pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
|
||||||
&frev, &crev, &data_offset)) {
|
ASIC_INTERNAL_ENGINE_SS, 0);
|
||||||
pi->sclk_ss = true;
|
pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
|
||||||
pi->mclk_ss = true;
|
ASIC_INTERNAL_MEMORY_SS, 0);
|
||||||
pi->dynamic_ss = true;
|
|
||||||
} else {
|
/* Disable sclk ss, causes hangs on a lot of systems */
|
||||||
pi->sclk_ss = false;
|
pi->sclk_ss = false;
|
||||||
pi->mclk_ss = false;
|
|
||||||
|
if (pi->sclk_ss || pi->mclk_ss)
|
||||||
|
pi->dynamic_ss = true;
|
||||||
|
else
|
||||||
pi->dynamic_ss = false;
|
pi->dynamic_ss = false;
|
||||||
}
|
|
||||||
|
|
||||||
pi->dynamic_pcie_gen2 = true;
|
pi->dynamic_pcie_gen2 = true;
|
||||||
|
|
||||||
|
@ -813,7 +813,7 @@ int rv770_uvd_resume(struct radeon_device *rdev)
|
|||||||
|
|
||||||
/* programm the VCPU memory controller bits 0-27 */
|
/* programm the VCPU memory controller bits 0-27 */
|
||||||
addr = rdev->uvd.gpu_addr >> 3;
|
addr = rdev->uvd.gpu_addr >> 3;
|
||||||
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
|
size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
|
||||||
WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
|
WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
|
||||||
WREG32(UVD_VCPU_CACHE_SIZE0, size);
|
WREG32(UVD_VCPU_CACHE_SIZE0, size);
|
||||||
|
|
||||||
@ -1829,6 +1829,8 @@ static int rv770_startup(struct radeon_device *rdev)
|
|||||||
/* enable pcie gen2 link */
|
/* enable pcie gen2 link */
|
||||||
rv770_pcie_gen2_enable(rdev);
|
rv770_pcie_gen2_enable(rdev);
|
||||||
|
|
||||||
|
rv770_mc_program(rdev);
|
||||||
|
|
||||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
|
||||||
r = r600_init_microcode(rdev);
|
r = r600_init_microcode(rdev);
|
||||||
if (r) {
|
if (r) {
|
||||||
@ -1841,7 +1843,6 @@ static int rv770_startup(struct radeon_device *rdev)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
rv770_mc_program(rdev);
|
|
||||||
if (rdev->flags & RADEON_IS_AGP) {
|
if (rdev->flags & RADEON_IS_AGP) {
|
||||||
rv770_agp_enable(rdev);
|
rv770_agp_enable(rdev);
|
||||||
} else {
|
} else {
|
||||||
@ -1983,6 +1984,7 @@ int rv770_resume(struct radeon_device *rdev)
|
|||||||
int rv770_suspend(struct radeon_device *rdev)
|
int rv770_suspend(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
r600_audio_fini(rdev);
|
r600_audio_fini(rdev);
|
||||||
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_suspend(rdev);
|
radeon_uvd_suspend(rdev);
|
||||||
r700_cp_stop(rdev);
|
r700_cp_stop(rdev);
|
||||||
r600_dma_stop(rdev);
|
r600_dma_stop(rdev);
|
||||||
@ -2098,6 +2100,7 @@ void rv770_fini(struct radeon_device *rdev)
|
|||||||
radeon_ib_pool_fini(rdev);
|
radeon_ib_pool_fini(rdev);
|
||||||
radeon_irq_kms_fini(rdev);
|
radeon_irq_kms_fini(rdev);
|
||||||
rv770_pcie_gart_fini(rdev);
|
rv770_pcie_gart_fini(rdev);
|
||||||
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_fini(rdev);
|
radeon_uvd_fini(rdev);
|
||||||
r600_vram_scratch_fini(rdev);
|
r600_vram_scratch_fini(rdev);
|
||||||
radeon_gem_fini(rdev);
|
radeon_gem_fini(rdev);
|
||||||
|
@ -2319,12 +2319,25 @@ int rv7xx_parse_power_table(struct radeon_device *rdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rv770_get_engine_memory_ss(struct radeon_device *rdev)
|
||||||
|
{
|
||||||
|
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
|
||||||
|
struct radeon_atom_ss ss;
|
||||||
|
|
||||||
|
pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
|
||||||
|
ASIC_INTERNAL_ENGINE_SS, 0);
|
||||||
|
pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
|
||||||
|
ASIC_INTERNAL_MEMORY_SS, 0);
|
||||||
|
|
||||||
|
if (pi->sclk_ss || pi->mclk_ss)
|
||||||
|
pi->dynamic_ss = true;
|
||||||
|
else
|
||||||
|
pi->dynamic_ss = false;
|
||||||
|
}
|
||||||
|
|
||||||
int rv770_dpm_init(struct radeon_device *rdev)
|
int rv770_dpm_init(struct radeon_device *rdev)
|
||||||
{
|
{
|
||||||
struct rv7xx_power_info *pi;
|
struct rv7xx_power_info *pi;
|
||||||
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
|
|
||||||
uint16_t data_offset, size;
|
|
||||||
uint8_t frev, crev;
|
|
||||||
struct atom_clock_dividers dividers;
|
struct atom_clock_dividers dividers;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -2369,16 +2382,7 @@ int rv770_dpm_init(struct radeon_device *rdev)
|
|||||||
pi->mvdd_control =
|
pi->mvdd_control =
|
||||||
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
|
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
|
||||||
|
|
||||||
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
|
rv770_get_engine_memory_ss(rdev);
|
||||||
&frev, &crev, &data_offset)) {
|
|
||||||
pi->sclk_ss = true;
|
|
||||||
pi->mclk_ss = true;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
} else {
|
|
||||||
pi->sclk_ss = false;
|
|
||||||
pi->mclk_ss = false;
|
|
||||||
pi->dynamic_ss = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pi->asi = RV770_ASI_DFLT;
|
pi->asi = RV770_ASI_DFLT;
|
||||||
pi->pasi = RV770_HASI_DFLT;
|
pi->pasi = RV770_HASI_DFLT;
|
||||||
@ -2393,8 +2397,7 @@ int rv770_dpm_init(struct radeon_device *rdev)
|
|||||||
|
|
||||||
pi->dynamic_pcie_gen2 = true;
|
pi->dynamic_pcie_gen2 = true;
|
||||||
|
|
||||||
if (pi->gfx_clock_gating &&
|
if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
|
||||||
(rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
|
|
||||||
pi->thermal_protection = true;
|
pi->thermal_protection = true;
|
||||||
else
|
else
|
||||||
pi->thermal_protection = false;
|
pi->thermal_protection = false;
|
||||||
|
@ -275,6 +275,7 @@ void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
|
|||||||
void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
|
void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
|
||||||
struct radeon_ps *new_ps,
|
struct radeon_ps *new_ps,
|
||||||
struct radeon_ps *old_ps);
|
struct radeon_ps *old_ps);
|
||||||
|
void rv770_get_engine_memory_ss(struct radeon_device *rdev);
|
||||||
|
|
||||||
/* smc */
|
/* smc */
|
||||||
int rv770_read_smc_soft_register(struct radeon_device *rdev,
|
int rv770_read_smc_soft_register(struct radeon_device *rdev,
|
||||||
|
@ -1663,9 +1663,13 @@ static int si_init_microcode(struct radeon_device *rdev)
|
|||||||
|
|
||||||
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
|
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
|
||||||
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
|
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
|
||||||
if (err)
|
if (err) {
|
||||||
goto out;
|
printk(KERN_ERR
|
||||||
if (rdev->smc_fw->size != smc_req_size) {
|
"smc: error loading firmware \"%s\"\n",
|
||||||
|
fw_name);
|
||||||
|
release_firmware(rdev->smc_fw);
|
||||||
|
rdev->smc_fw = NULL;
|
||||||
|
} 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",
|
||||||
rdev->smc_fw->size, fw_name);
|
rdev->smc_fw->size, fw_name);
|
||||||
@ -6418,6 +6422,8 @@ static int si_startup(struct radeon_device *rdev)
|
|||||||
/* enable aspm */
|
/* enable aspm */
|
||||||
si_program_aspm(rdev);
|
si_program_aspm(rdev);
|
||||||
|
|
||||||
|
si_mc_program(rdev);
|
||||||
|
|
||||||
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
|
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
|
||||||
!rdev->rlc_fw || !rdev->mc_fw) {
|
!rdev->rlc_fw || !rdev->mc_fw) {
|
||||||
r = si_init_microcode(rdev);
|
r = si_init_microcode(rdev);
|
||||||
@ -6437,7 +6443,6 @@ static int si_startup(struct radeon_device *rdev)
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
si_mc_program(rdev);
|
|
||||||
r = si_pcie_gart_enable(rdev);
|
r = si_pcie_gart_enable(rdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
@ -6621,7 +6626,7 @@ int si_suspend(struct radeon_device *rdev)
|
|||||||
si_cp_enable(rdev, false);
|
si_cp_enable(rdev, false);
|
||||||
cayman_dma_stop(rdev);
|
cayman_dma_stop(rdev);
|
||||||
if (rdev->has_uvd) {
|
if (rdev->has_uvd) {
|
||||||
r600_uvd_rbc_stop(rdev);
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_suspend(rdev);
|
radeon_uvd_suspend(rdev);
|
||||||
}
|
}
|
||||||
si_irq_suspend(rdev);
|
si_irq_suspend(rdev);
|
||||||
@ -6763,8 +6768,10 @@ void si_fini(struct radeon_device *rdev)
|
|||||||
radeon_vm_manager_fini(rdev);
|
radeon_vm_manager_fini(rdev);
|
||||||
radeon_ib_pool_fini(rdev);
|
radeon_ib_pool_fini(rdev);
|
||||||
radeon_irq_kms_fini(rdev);
|
radeon_irq_kms_fini(rdev);
|
||||||
if (rdev->has_uvd)
|
if (rdev->has_uvd) {
|
||||||
|
r600_uvd_stop(rdev);
|
||||||
radeon_uvd_fini(rdev);
|
radeon_uvd_fini(rdev);
|
||||||
|
}
|
||||||
si_pcie_gart_fini(rdev);
|
si_pcie_gart_fini(rdev);
|
||||||
r600_vram_scratch_fini(rdev);
|
r600_vram_scratch_fini(rdev);
|
||||||
radeon_gem_fini(rdev);
|
radeon_gem_fini(rdev);
|
||||||
|
@ -2903,7 +2903,8 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
|||||||
{
|
{
|
||||||
struct ni_ps *ps = ni_get_ps(rps);
|
struct ni_ps *ps = ni_get_ps(rps);
|
||||||
struct radeon_clock_and_voltage_limits *max_limits;
|
struct radeon_clock_and_voltage_limits *max_limits;
|
||||||
bool disable_mclk_switching;
|
bool disable_mclk_switching = false;
|
||||||
|
bool disable_sclk_switching = false;
|
||||||
u32 mclk, sclk;
|
u32 mclk, sclk;
|
||||||
u16 vddc, vddci;
|
u16 vddc, vddci;
|
||||||
int i;
|
int i;
|
||||||
@ -2911,8 +2912,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
|||||||
if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
|
if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
|
||||||
ni_dpm_vblank_too_short(rdev))
|
ni_dpm_vblank_too_short(rdev))
|
||||||
disable_mclk_switching = true;
|
disable_mclk_switching = true;
|
||||||
else
|
|
||||||
disable_mclk_switching = false;
|
if (rps->vclk || rps->dclk) {
|
||||||
|
disable_mclk_switching = true;
|
||||||
|
disable_sclk_switching = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (rdev->pm.dpm.ac_power)
|
if (rdev->pm.dpm.ac_power)
|
||||||
max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
|
max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
|
||||||
@ -2940,28 +2944,44 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
|
|||||||
|
|
||||||
if (disable_mclk_switching) {
|
if (disable_mclk_switching) {
|
||||||
mclk = ps->performance_levels[ps->performance_level_count - 1].mclk;
|
mclk = ps->performance_levels[ps->performance_level_count - 1].mclk;
|
||||||
sclk = ps->performance_levels[0].sclk;
|
|
||||||
vddc = ps->performance_levels[0].vddc;
|
|
||||||
vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
|
vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
|
||||||
} else {
|
} else {
|
||||||
sclk = ps->performance_levels[0].sclk;
|
|
||||||
mclk = ps->performance_levels[0].mclk;
|
mclk = ps->performance_levels[0].mclk;
|
||||||
vddc = ps->performance_levels[0].vddc;
|
|
||||||
vddci = ps->performance_levels[0].vddci;
|
vddci = ps->performance_levels[0].vddci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (disable_sclk_switching) {
|
||||||
|
sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;
|
||||||
|
vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;
|
||||||
|
} else {
|
||||||
|
sclk = ps->performance_levels[0].sclk;
|
||||||
|
vddc = ps->performance_levels[0].vddc;
|
||||||
|
}
|
||||||
|
|
||||||
/* adjusted low state */
|
/* adjusted low state */
|
||||||
ps->performance_levels[0].sclk = sclk;
|
ps->performance_levels[0].sclk = sclk;
|
||||||
ps->performance_levels[0].mclk = mclk;
|
ps->performance_levels[0].mclk = mclk;
|
||||||
ps->performance_levels[0].vddc = vddc;
|
ps->performance_levels[0].vddc = vddc;
|
||||||
ps->performance_levels[0].vddci = vddci;
|
ps->performance_levels[0].vddci = vddci;
|
||||||
|
|
||||||
|
if (disable_sclk_switching) {
|
||||||
|
sclk = ps->performance_levels[0].sclk;
|
||||||
|
for (i = 1; i < ps->performance_level_count; i++) {
|
||||||
|
if (sclk < ps->performance_levels[i].sclk)
|
||||||
|
sclk = ps->performance_levels[i].sclk;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ps->performance_level_count; i++) {
|
||||||
|
ps->performance_levels[i].sclk = sclk;
|
||||||
|
ps->performance_levels[i].vddc = vddc;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for (i = 1; i < ps->performance_level_count; i++) {
|
for (i = 1; i < ps->performance_level_count; i++) {
|
||||||
if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
|
if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
|
||||||
ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
|
ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
|
||||||
if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
|
if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
|
||||||
ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
|
ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (disable_mclk_switching) {
|
if (disable_mclk_switching) {
|
||||||
mclk = ps->performance_levels[0].mclk;
|
mclk = ps->performance_levels[0].mclk;
|
||||||
@ -6253,9 +6273,6 @@ int si_dpm_init(struct radeon_device *rdev)
|
|||||||
struct evergreen_power_info *eg_pi;
|
struct evergreen_power_info *eg_pi;
|
||||||
struct ni_power_info *ni_pi;
|
struct ni_power_info *ni_pi;
|
||||||
struct si_power_info *si_pi;
|
struct si_power_info *si_pi;
|
||||||
int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
|
|
||||||
u16 data_offset, size;
|
|
||||||
u8 frev, crev;
|
|
||||||
struct atom_clock_dividers dividers;
|
struct atom_clock_dividers dividers;
|
||||||
int ret;
|
int ret;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
@ -6346,16 +6363,7 @@ int si_dpm_init(struct radeon_device *rdev)
|
|||||||
si_pi->vddc_phase_shed_control =
|
si_pi->vddc_phase_shed_control =
|
||||||
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT);
|
radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT);
|
||||||
|
|
||||||
if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
|
rv770_get_engine_memory_ss(rdev);
|
||||||
&frev, &crev, &data_offset)) {
|
|
||||||
pi->sclk_ss = true;
|
|
||||||
pi->mclk_ss = true;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
} else {
|
|
||||||
pi->sclk_ss = false;
|
|
||||||
pi->mclk_ss = false;
|
|
||||||
pi->dynamic_ss = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pi->asi = RV770_ASI_DFLT;
|
pi->asi = RV770_ASI_DFLT;
|
||||||
pi->pasi = CYPRESS_HASI_DFLT;
|
pi->pasi = CYPRESS_HASI_DFLT;
|
||||||
@ -6366,8 +6374,7 @@ int si_dpm_init(struct radeon_device *rdev)
|
|||||||
eg_pi->sclk_deep_sleep = true;
|
eg_pi->sclk_deep_sleep = true;
|
||||||
si_pi->sclk_deep_sleep_above_low = false;
|
si_pi->sclk_deep_sleep_above_low = false;
|
||||||
|
|
||||||
if (pi->gfx_clock_gating &&
|
if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
|
||||||
(rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
|
|
||||||
pi->thermal_protection = true;
|
pi->thermal_protection = true;
|
||||||
else
|
else
|
||||||
pi->thermal_protection = false;
|
pi->thermal_protection = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user