diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 106 | 
1 files changed, 83 insertions, 23 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 4e777c1e4b7..19afc43ad17 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -763,13 +763,14 @@ void r600_hpd_init(struct radeon_device *rdev)  	struct drm_device *dev = rdev->ddev;  	struct drm_connector *connector; -	if (ASIC_IS_DCE3(rdev)) { -		u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); -		if (ASIC_IS_DCE32(rdev)) -			tmp |= DC_HPDx_EN; +	list_for_each_entry(connector, &dev->mode_config.connector_list, head) { +		struct radeon_connector *radeon_connector = to_radeon_connector(connector); + +		if (ASIC_IS_DCE3(rdev)) { +			u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); +			if (ASIC_IS_DCE32(rdev)) +				tmp |= DC_HPDx_EN; -		list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -			struct radeon_connector *radeon_connector = to_radeon_connector(connector);  			switch (radeon_connector->hpd.hpd) {  			case RADEON_HPD_1:  				WREG32(DC_HPD1_CONTROL, tmp); @@ -799,10 +800,7 @@ void r600_hpd_init(struct radeon_device *rdev)  			default:  				break;  			} -		} -	} else { -		list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -			struct radeon_connector *radeon_connector = to_radeon_connector(connector); +		} else {  			switch (radeon_connector->hpd.hpd) {  			case RADEON_HPD_1:  				WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); @@ -820,6 +818,7 @@ void r600_hpd_init(struct radeon_device *rdev)  				break;  			}  		} +		radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);  	}  	if (rdev->irq.installed)  		r600_irq_set(rdev); @@ -897,7 +896,7 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)  	/* flush hdp cache so updates hit vram */  	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&  	    !(rdev->flags & RADEON_IS_AGP)) { -		void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; +		void __iomem *ptr = (void *)rdev->gart.ptr;  		u32 tmp;  		/* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read @@ -932,7 +931,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev)  {  	int r; -	if (rdev->gart.table.vram.robj) { +	if (rdev->gart.robj) {  		WARN(1, "R600 PCIE GART already initialized\n");  		return 0;  	} @@ -949,7 +948,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)  	u32 tmp;  	int r, i; -	if (rdev->gart.table.vram.robj == NULL) { +	if (rdev->gart.robj == NULL) {  		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");  		return -EINVAL;  	} @@ -1004,7 +1003,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)  void r600_pcie_gart_disable(struct radeon_device *rdev)  {  	u32 tmp; -	int i, r; +	int i;  	/* Disable all tables */  	for (i = 0; i < 7; i++) @@ -1031,14 +1030,7 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)  	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);  	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);  	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); -	if (rdev->gart.table.vram.robj) { -		r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); -		if (likely(r == 0)) { -			radeon_bo_kunmap(rdev->gart.table.vram.robj); -			radeon_bo_unpin(rdev->gart.table.vram.robj); -			radeon_bo_unreserve(rdev->gart.table.vram.robj); -		} -	} +	radeon_gart_table_vram_unpin(rdev);  }  void r600_pcie_gart_fini(struct radeon_device *rdev) @@ -1138,7 +1130,7 @@ static void r600_mc_program(struct radeon_device *rdev)  		WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);  		WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);  	} -	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); +	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);  	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;  	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);  	WREG32(MC_VM_FB_LOCATION, tmp); @@ -1277,6 +1269,53 @@ int r600_mc_init(struct radeon_device *rdev)  	return 0;  } +int r600_vram_scratch_init(struct radeon_device *rdev) +{ +	int r; + +	if (rdev->vram_scratch.robj == NULL) { +		r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, +				     PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, +				     &rdev->vram_scratch.robj); +		if (r) { +			return r; +		} +	} + +	r = radeon_bo_reserve(rdev->vram_scratch.robj, false); +	if (unlikely(r != 0)) +		return r; +	r = radeon_bo_pin(rdev->vram_scratch.robj, +			  RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr); +	if (r) { +		radeon_bo_unreserve(rdev->vram_scratch.robj); +		return r; +	} +	r = radeon_bo_kmap(rdev->vram_scratch.robj, +				(void **)&rdev->vram_scratch.ptr); +	if (r) +		radeon_bo_unpin(rdev->vram_scratch.robj); +	radeon_bo_unreserve(rdev->vram_scratch.robj); + +	return r; +} + +void r600_vram_scratch_fini(struct radeon_device *rdev) +{ +	int r; + +	if (rdev->vram_scratch.robj == NULL) { +		return; +	} +	r = radeon_bo_reserve(rdev->vram_scratch.robj, false); +	if (likely(r == 0)) { +		radeon_bo_kunmap(rdev->vram_scratch.robj); +		radeon_bo_unpin(rdev->vram_scratch.robj); +		radeon_bo_unreserve(rdev->vram_scratch.robj); +	} +	radeon_bo_unref(&rdev->vram_scratch.robj); +} +  /* We doesn't check that the GPU really needs a reset we simply do the   * reset, it's up to the caller to determine if the GPU needs one. We   * might add an helper function to check that. @@ -2332,6 +2371,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,  	if (rdev->wb.use_event) {  		u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET +  			(u64)(rdev->fence_drv.scratch_reg - rdev->scratch.reg_base); +		/* flush read cache over gart */ +		radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); +		radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | +					PACKET3_VC_ACTION_ENA | +					PACKET3_SH_ACTION_ENA); +		radeon_ring_write(rdev, 0xFFFFFFFF); +		radeon_ring_write(rdev, 0); +		radeon_ring_write(rdev, 10); /* poll interval */  		/* EVENT_WRITE_EOP - flush caches, send int */  		radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));  		radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); @@ -2340,6 +2387,14 @@ void r600_fence_ring_emit(struct radeon_device *rdev,  		radeon_ring_write(rdev, fence->seq);  		radeon_ring_write(rdev, 0);  	} else { +		/* flush read cache over gart */ +		radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); +		radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | +					PACKET3_VC_ACTION_ENA | +					PACKET3_SH_ACTION_ENA); +		radeon_ring_write(rdev, 0xFFFFFFFF); +		radeon_ring_write(rdev, 0); +		radeon_ring_write(rdev, 10); /* poll interval */  		radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));  		radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0));  		/* wait for 3D idle clean */ @@ -2421,6 +2476,10 @@ int r600_startup(struct radeon_device *rdev)  		}  	} +	r = r600_vram_scratch_init(rdev); +	if (r) +		return r; +  	r600_mc_program(rdev);  	if (rdev->flags & RADEON_IS_AGP) {  		r600_agp_enable(rdev); @@ -2641,6 +2700,7 @@ void r600_fini(struct radeon_device *rdev)  	radeon_ib_pool_fini(rdev);  	radeon_irq_kms_fini(rdev);  	r600_pcie_gart_fini(rdev); +	r600_vram_scratch_fini(rdev);  	radeon_agp_fini(rdev);  	radeon_gem_fini(rdev);  	radeon_fence_driver_fini(rdev);  |