diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/rs400.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/rs400.c | 95 | 
1 files changed, 66 insertions, 29 deletions
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 5512e4e5e63..a0f96decece 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -77,7 +77,7 @@ int rs400_gart_init(struct radeon_device *rdev)  {  	int r; -	if (rdev->gart.table.ram.ptr) { +	if (rdev->gart.ptr) {  		WARN(1, "RS400 GART already initialized\n");  		return 0;  	} @@ -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; @@ -403,25 +415,41 @@ static int rs400_startup(struct radeon_device *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_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 */ @@ -440,11 +468,18 @@ 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);  	radeon_wb_disable(rdev);  	r100_irq_disable(rdev); @@ -454,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);  	radeon_wb_fini(rdev); -	r100_ib_fini(rdev); +	radeon_ib_pool_fini(rdev);  	radeon_gem_fini(rdev);  	rs400_gart_fini(rdev);  	radeon_irq_kms_fini(rdev); @@ -512,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) @@ -523,6 +556,10 @@ 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) { @@ -530,7 +567,7 @@ int rs400_init(struct radeon_device *rdev)  		dev_err(rdev->dev, "Disabling GPU acceleration\n");  		r100_cp_fini(rdev);  		radeon_wb_fini(rdev); -		r100_ib_fini(rdev); +		radeon_ib_pool_fini(rdev);  		rs400_gart_fini(rdev);  		radeon_irq_kms_fini(rdev);  		rdev->accel_working = false;  | 
