#include "radeon_ucode.h"
#include "clearstate_cayman.h"
+/*
+ * Indirect registers accessor
+ */
+u32 tn_smc_rreg(struct radeon_device *rdev, u32 reg)
+{
+ unsigned long flags;
+ u32 r;
+
+ spin_lock_irqsave(&rdev->smc_idx_lock, flags);
+ WREG32(TN_SMC_IND_INDEX_0, (reg));
+ r = RREG32(TN_SMC_IND_DATA_0);
+ spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
+ return r;
+}
+
+void tn_smc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rdev->smc_idx_lock, flags);
+ WREG32(TN_SMC_IND_INDEX_0, (reg));
+ WREG32(TN_SMC_IND_DATA_0, (v));
+ spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
+}
+
static const u32 tn_rlc_save_restore_register_list[] =
{
0x98fc,
if (r)
rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+ if (rdev->family == CHIP_ARUBA) {
+ r = radeon_vce_resume(rdev);
+ if (!r)
+ r = vce_v1_0_resume(rdev);
+
+ if (!r)
+ r = radeon_fence_driver_start_ring(rdev,
+ TN_RING_TYPE_VCE1_INDEX);
+ if (!r)
+ r = radeon_fence_driver_start_ring(rdev,
+ TN_RING_TYPE_VCE2_INDEX);
+
+ if (r) {
+ dev_err(rdev->dev, "VCE init error (%d).\n", r);
+ rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
+ rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
+ }
+ }
+
r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
if (r) {
dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
}
+ if (rdev->family == CHIP_ARUBA) {
+ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
+ if (ring->ring_size)
+ r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
+
+ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
+ if (ring->ring_size)
+ r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
+
+ if (!r)
+ r = vce_v1_0_init(rdev);
+ if (r)
+ DRM_ERROR("radeon: failed initializing VCE (%d).\n", r);
+ }
+
r = radeon_ib_pool_init(rdev);
if (r) {
dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
r600_ring_init(rdev, ring, 4096);
}
+ if (rdev->family == CHIP_ARUBA) {
+ r = radeon_vce_init(rdev);
+ if (!r) {
+ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 4096);
+
+ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
+ ring->ring_obj = NULL;
+ r600_ring_init(rdev, ring, 4096);
+ }
+ }
+
rdev->ih.ring_obj = NULL;
r600_ih_ring_init(rdev, 64 * 1024);
radeon_irq_kms_fini(rdev);
uvd_v1_0_fini(rdev);
radeon_uvd_fini(rdev);
+ if (rdev->family == CHIP_ARUBA)
+ radeon_vce_fini(rdev);
cayman_pcie_gart_fini(rdev);
r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
radeon_ring_write(ring, 0x0);
}
+
+int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
+{
+ struct atom_clock_dividers dividers;
+ int r, i;
+
+ r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+ ecclk, false, ÷rs);
+ if (r)
+ return r;
+
+ for (i = 0; i < 100; i++) {
+ if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
+ break;
+ mdelay(10);
+ }
+ if (i == 100)
+ return -ETIMEDOUT;
+
+ WREG32_P(CG_ECLK_CNTL, dividers.post_div, ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK));
+
+ for (i = 0; i < 100; i++) {
+ if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
+ break;
+ mdelay(10);
+ }
+ if (i == 100)
+ return -ETIMEDOUT;
+
+ return 0;
+}