diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/rs400.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/rs400.c | 112 |
1 files changed, 76 insertions, 36 deletions
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index ae2b76b9a38..a0f96decece 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -77,8 +77,8 @@ int rs400_gart_init(struct radeon_device *rdev) { int r; - if (rdev->gart.table.ram.ptr) { - WARN(1, "RS400 GART already initialized.\n"); + if (rdev->gart.ptr) { + WARN(1, "RS400 GART already initialized\n"); return 0; } /* Check gart size */ @@ -174,14 +174,20 @@ int rs400_gart_enable(struct radeon_device *rdev) /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0, * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */ if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { - WREG32_MC(RS480_MC_MISC_CNTL, - (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN)); + tmp = RREG32_MC(RS480_MC_MISC_CNTL); + tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN; + WREG32_MC(RS480_MC_MISC_CNTL, tmp); } else { - WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); + tmp = RREG32_MC(RS480_MC_MISC_CNTL); + tmp |= RS480_GART_INDEX_REG_EN; + WREG32_MC(RS480_MC_MISC_CNTL, tmp); } /* Enable gart */ WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg)); rs400_gart_tlb_flush(rdev); + DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", + (unsigned)(rdev->mc.gtt_size >> 20), + (unsigned long long)rdev->gart.table_addr); rdev->gart.ready = true; return 0; } @@ -203,20 +209,19 @@ void rs400_gart_fini(struct radeon_device *rdev) radeon_gart_table_ram_free(rdev); } -int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) +#define RS400_PTE_WRITEABLE (1 << 2) +#define RS400_PTE_READABLE (1 << 3) + +void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, uint64_t addr) { uint32_t entry; - - if (i < 0 || i > rdev->gart.num_gpu_pages) { - return -EINVAL; - } + u32 *gtt = rdev->gart.ptr; entry = (lower_32_bits(addr) & PAGE_MASK) | ((upper_32_bits(addr) & 0xff) << 4) | - 0xc; + RS400_PTE_WRITEABLE | RS400_PTE_READABLE; entry = cpu_to_le32(entry); - rdev->gart.table.ram.ptr[i] = entry; - return 0; + gtt[i] = entry; } int rs400_mc_wait_for_idle(struct radeon_device *rdev) @@ -226,8 +231,8 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev) for (i = 0; i < rdev->usec_timeout; i++) { /* read MC_STATUS */ - tmp = RREG32(0x0150); - if (tmp & (1 << 2)) { + tmp = RREG32(RADEON_MC_STATUS); + if (tmp & RADEON_MC_IDLE) { return 0; } DRM_UDELAY(1); @@ -235,17 +240,17 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev) return -1; } -void rs400_gpu_init(struct radeon_device *rdev) +static void rs400_gpu_init(struct radeon_device *rdev) { /* FIXME: is this correct ? */ r420_pipes_init(rdev); if (rs400_mc_wait_for_idle(rdev)) { printk(KERN_WARNING "rs400: Failed to wait MC idle while " - "programming pipes. Bad things might happen. %08x\n", RREG32(0x150)); + "programming pipes. Bad things might happen. %08x\n", RREG32(RADEON_MC_STATUS)); } } -void rs400_mc_init(struct radeon_device *rdev) +static void rs400_mc_init(struct radeon_device *rdev) { u64 base; @@ -264,19 +269,26 @@ void rs400_mc_init(struct radeon_device *rdev) uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg) { + unsigned long flags; uint32_t r; + spin_lock_irqsave(&rdev->mc_idx_lock, flags); WREG32(RS480_NB_MC_INDEX, reg & 0xff); r = RREG32(RS480_NB_MC_DATA); WREG32(RS480_NB_MC_INDEX, 0xff); + spin_unlock_irqrestore(&rdev->mc_idx_lock, flags); return r; } void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) { + unsigned long flags; + + spin_lock_irqsave(&rdev->mc_idx_lock, flags); WREG32(RS480_NB_MC_INDEX, ((reg) & 0xff) | RS480_NB_MC_IND_WR_EN); WREG32(RS480_NB_MC_DATA, (v)); WREG32(RS480_NB_MC_INDEX, 0xff); + spin_unlock_irqrestore(&rdev->mc_idx_lock, flags); } #if defined(CONFIG_DEBUG_FS) @@ -300,9 +312,9 @@ static int rs400_debugfs_gart_info(struct seq_file *m, void *data) seq_printf(m, "MCCFG_AGP_BASE_2 0x%08x\n", tmp); tmp = RREG32_MC(RS690_MCCFG_AGP_LOCATION); seq_printf(m, "MCCFG_AGP_LOCATION 0x%08x\n", tmp); - tmp = RREG32_MC(0x100); + tmp = RREG32_MC(RS690_MCCFG_FB_LOCATION); seq_printf(m, "MCCFG_FB_LOCATION 0x%08x\n", tmp); - tmp = RREG32(0x134); + tmp = RREG32(RS690_HDP_FB_LOCATION); seq_printf(m, "HDP_FB_LOCATION 0x%08x\n", tmp); } else { tmp = RREG32(RADEON_AGP_BASE); @@ -363,7 +375,7 @@ static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev) #endif } -void rs400_mc_program(struct radeon_device *rdev) +static void rs400_mc_program(struct radeon_device *rdev) { struct r100_mc_save save; @@ -397,28 +409,47 @@ static int rs400_startup(struct radeon_device *rdev) r = rs400_gart_enable(rdev); if (r) return r; + + /* allocate wb buffer */ + r = radeon_wb_init(rdev); + if (r) + return r; + + r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); + return r; + } + /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); + if (r) + return r; + } + r100_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); /* 1M ring buffer */ r = r100_cp_init(rdev, 1024 * 1024); if (r) { - dev_err(rdev->dev, "failled initializing CP (%d).\n", r); + dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_wb_init(rdev); - if (r) - dev_err(rdev->dev, "failled initializing WB (%d).\n", r); - r = r100_ib_init(rdev); + + r = radeon_ib_pool_init(rdev); if (r) { - dev_err(rdev->dev, "failled initializing IB (%d).\n", r); + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); return r; } + return 0; } int rs400_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ rs400_gart_disable(rdev); /* Resume clock before doing reset */ @@ -437,13 +468,20 @@ int rs400_resume(struct radeon_device *rdev) r300_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); - return rs400_startup(rdev); + + rdev->accel_working = true; + r = rs400_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int rs400_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r100_cp_disable(rdev); - r100_wb_disable(rdev); + radeon_wb_disable(rdev); r100_irq_disable(rdev); rs400_gart_disable(rdev); return 0; @@ -451,9 +489,10 @@ int rs400_suspend(struct radeon_device *rdev) void rs400_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); - r100_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_wb_fini(rdev); + radeon_ib_pool_fini(rdev); radeon_gem_fini(rdev); rs400_gart_fini(rdev); radeon_irq_kms_fini(rdev); @@ -509,9 +548,6 @@ int rs400_init(struct radeon_device *rdev) r = radeon_fence_driver_init(rdev); if (r) return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) @@ -520,14 +556,18 @@ int rs400_init(struct radeon_device *rdev) if (r) return r; r300_set_reg_safe(rdev); + + /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = rs400_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ dev_err(rdev->dev, "Disabling GPU acceleration\n"); r100_cp_fini(rdev); - r100_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_wb_fini(rdev); + radeon_ib_pool_fini(rdev); rs400_gart_fini(rdev); radeon_irq_kms_fini(rdev); rdev->accel_working = false; |
