diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/rs690.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/rs690.c | 38 | 
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index d8ddfb34545..3462b64369b 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -162,6 +162,16 @@ static void rs690_mc_init(struct radeon_device *rdev)  	base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);  	base = G_000100_MC_FB_START(base) << 16;  	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); +	/* Some boards seem to be configured for 128MB of sideport memory, +	 * but really only have 64MB.  Just skip the sideport and use +	 * UMA memory. +	 */ +	if (rdev->mc.igp_sideport_enabled && +	    (rdev->mc.real_vram_size == (384 * 1024 * 1024))) { +		base += 128 * 1024 * 1024; +		rdev->mc.real_vram_size -= 128 * 1024 * 1024; +		rdev->mc.mc_vram_size = rdev->mc.real_vram_size; +	}  	/* Use K8 direct mapping for fast fb access. */   	rdev->fastfb_working = false; @@ -345,9 +355,11 @@ static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,  		if (max_bandwidth.full > rdev->pm.sideport_bandwidth.full &&  			rdev->pm.sideport_bandwidth.full)  			max_bandwidth = rdev->pm.sideport_bandwidth; -		read_delay_latency.full = dfixed_const(370 * 800 * 1000); -		read_delay_latency.full = dfixed_div(read_delay_latency, -			rdev->pm.igp_sideport_mclk); +		read_delay_latency.full = dfixed_const(370 * 800); +		a.full = dfixed_const(1000); +		b.full = dfixed_div(rdev->pm.igp_sideport_mclk, a); +		read_delay_latency.full = dfixed_div(read_delay_latency, b); +		read_delay_latency.full = dfixed_mul(read_delay_latency, a);  	} else {  		if (max_bandwidth.full > rdev->pm.k8_bandwidth.full &&  			rdev->pm.k8_bandwidth.full) @@ -488,14 +500,10 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev,  		}  		if (wm0->priority_mark.full > priority_mark02.full)  			priority_mark02.full = wm0->priority_mark.full; -		if (dfixed_trunc(priority_mark02) < 0) -			priority_mark02.full = 0;  		if (wm0->priority_mark_max.full > priority_mark02.full)  			priority_mark02.full = wm0->priority_mark_max.full;  		if (wm1->priority_mark.full > priority_mark12.full)  			priority_mark12.full = wm1->priority_mark.full; -		if (dfixed_trunc(priority_mark12) < 0) -			priority_mark12.full = 0;  		if (wm1->priority_mark_max.full > priority_mark12.full)  			priority_mark12.full = wm1->priority_mark_max.full;  		*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -526,8 +534,6 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev,  		}  		if (wm0->priority_mark.full > priority_mark02.full)  			priority_mark02.full = wm0->priority_mark.full; -		if (dfixed_trunc(priority_mark02) < 0) -			priority_mark02.full = 0;  		if (wm0->priority_mark_max.full > priority_mark02.full)  			priority_mark02.full = wm0->priority_mark_max.full;  		*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); @@ -555,8 +561,6 @@ static void rs690_compute_mode_priority(struct radeon_device *rdev,  		}  		if (wm1->priority_mark.full > priority_mark12.full)  			priority_mark12.full = wm1->priority_mark.full; -		if (dfixed_trunc(priority_mark12) < 0) -			priority_mark12.full = 0;  		if (wm1->priority_mark_max.full > priority_mark12.full)  			priority_mark12.full = wm1->priority_mark_max.full;  		*d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); @@ -631,20 +635,27 @@ void rs690_bandwidth_update(struct radeon_device *rdev)  uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)  { +	unsigned long flags;  	uint32_t r; +	spin_lock_irqsave(&rdev->mc_idx_lock, flags);  	WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg));  	r = RREG32(R_00007C_MC_DATA);  	WREG32(R_000078_MC_INDEX, ~C_000078_MC_IND_ADDR); +	spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);  	return r;  }  void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)  { +	unsigned long flags; + +	spin_lock_irqsave(&rdev->mc_idx_lock, flags);  	WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg) |  		S_000078_MC_IND_WR_EN(1));  	WREG32(R_00007C_MC_DATA, v);  	WREG32(R_000078_MC_INDEX, 0x7F); +	spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);  }  static void rs690_mc_program(struct radeon_device *rdev) @@ -755,6 +766,7 @@ int rs690_resume(struct radeon_device *rdev)  int rs690_suspend(struct radeon_device *rdev)  { +	radeon_pm_suspend(rdev);  	r600_audio_fini(rdev);  	r100_cp_disable(rdev);  	radeon_wb_disable(rdev); @@ -765,6 +777,7 @@ int rs690_suspend(struct radeon_device *rdev)  void rs690_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r600_audio_fini(rdev);  	r100_cp_fini(rdev);  	radeon_wb_fini(rdev); @@ -834,6 +847,9 @@ int rs690_init(struct radeon_device *rdev)  		return r;  	rs600_set_safe_registers(rdev); +	/* Initialize power management */ +	radeon_pm_init(rdev); +  	rdev->accel_working = true;  	r = rs690_startup(rdev);  	if (r) {  | 
