diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 86 | 
1 files changed, 36 insertions, 50 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index fb5fa089886..c4ffa14fb2f 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -41,6 +41,31 @@ static void evergreen_gpu_init(struct radeon_device *rdev);  void evergreen_fini(struct radeon_device *rdev);  static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); +void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) +{ +	u16 ctl, v; +	int cap, err; + +	cap = pci_pcie_cap(rdev->pdev); +	if (!cap) +		return; + +	err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); +	if (err) +		return; + +	v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12; + +	/* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it +	 * to avoid hangs or perfomance issues +	 */ +	if ((v == 0) || (v == 6) || (v == 7)) { +		ctl &= ~PCI_EXP_DEVCTL_READRQ; +		ctl |= (2 << 12); +		pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); +	} +} +  void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)  {  	/* enable the pflip int */ @@ -1357,6 +1382,7 @@ int evergreen_cp_resume(struct radeon_device *rdev)  				 SOFT_RESET_PA |  				 SOFT_RESET_SH |  				 SOFT_RESET_VGT | +				 SOFT_RESET_SPI |  				 SOFT_RESET_SX));  	RREG32(GRBM_SOFT_RESET);  	mdelay(15); @@ -1378,7 +1404,8 @@ int evergreen_cp_resume(struct radeon_device *rdev)  	/* Initialize the ring buffer's read and write pointers */  	WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);  	WREG32(CP_RB_RPTR_WR, 0); -	WREG32(CP_RB_WPTR, 0); +	rdev->cp.wptr = 0; +	WREG32(CP_RB_WPTR, rdev->cp.wptr);  	/* set the wb address wether it's enabled or not */  	WREG32(CP_RB_RPTR_ADDR, @@ -1400,7 +1427,6 @@ int evergreen_cp_resume(struct radeon_device *rdev)  	WREG32(CP_DEBUG, (1 << 27) | (1 << 28));  	rdev->cp.rptr = RREG32(CP_RB_RPTR); -	rdev->cp.wptr = RREG32(CP_RB_WPTR);  	evergreen_cp_start(rdev);  	rdev->cp.ready = true; @@ -1564,48 +1590,6 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev,  	return backend_map;  } -static void evergreen_program_channel_remap(struct radeon_device *rdev) -{ -	u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; - -	tmp = RREG32(MC_SHARED_CHMAP); -	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { -	case 0: -	case 1: -	case 2: -	case 3: -	default: -		/* default mapping */ -		mc_shared_chremap = 0x00fac688; -		break; -	} - -	switch (rdev->family) { -	case CHIP_HEMLOCK: -	case CHIP_CYPRESS: -	case CHIP_BARTS: -		tcp_chan_steer_lo = 0x54763210; -		tcp_chan_steer_hi = 0x0000ba98; -		break; -	case CHIP_JUNIPER: -	case CHIP_REDWOOD: -	case CHIP_CEDAR: -	case CHIP_PALM: -	case CHIP_SUMO: -	case CHIP_SUMO2: -	case CHIP_TURKS: -	case CHIP_CAICOS: -	default: -		tcp_chan_steer_lo = 0x76543210; -		tcp_chan_steer_hi = 0x0000ba98; -		break; -	} - -	WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); -	WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); -	WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); -} -  static void evergreen_gpu_init(struct radeon_device *rdev)  {  	u32 cc_rb_backend_disable = 0; @@ -1862,6 +1846,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)  	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); +	evergreen_fix_pci_max_read_req_size(rdev); +  	cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2;  	cc_gc_shader_pipe_config |= @@ -2050,8 +2036,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)  	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);  	WREG32(HDP_ADDR_CONFIG, gb_addr_config); -	evergreen_program_channel_remap(rdev); -  	num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1;  	grbm_gfx_index = INSTANCE_BROADCAST_WRITES; @@ -3143,21 +3127,23 @@ int evergreen_suspend(struct radeon_device *rdev)  }  int evergreen_copy_blit(struct radeon_device *rdev, -			uint64_t src_offset, uint64_t dst_offset, -			unsigned num_pages, struct radeon_fence *fence) +			uint64_t src_offset, +			uint64_t dst_offset, +			unsigned num_gpu_pages, +			struct radeon_fence *fence)  {  	int r;  	mutex_lock(&rdev->r600_blit.mutex);  	rdev->r600_blit.vb_ib = NULL; -	r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); +	r = evergreen_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE);  	if (r) {  		if (rdev->r600_blit.vb_ib)  			radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);  		mutex_unlock(&rdev->r600_blit.mutex);  		return r;  	} -	evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); +	evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE);  	evergreen_blit_done_copy(rdev, fence);  	mutex_unlock(&rdev->r600_blit.mutex);  	return 0;  |