aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r420.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/gpu/drm/radeon/r420.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/gpu/drm/radeon/r420.c')
-rw-r--r--drivers/gpu/drm/radeon/r420.c123
1 files changed, 75 insertions, 48 deletions
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 1cefdbcc0850..c2bda4ad62e7 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -26,34 +26,20 @@
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28#include <linux/seq_file.h> 28#include <linux/seq_file.h>
29#include <linux/slab.h>
29#include "drmP.h" 30#include "drmP.h"
30#include "radeon_reg.h" 31#include "radeon_reg.h"
31#include "radeon.h" 32#include "radeon.h"
33#include "radeon_asic.h"
32#include "atom.h" 34#include "atom.h"
35#include "r100d.h"
33#include "r420d.h" 36#include "r420d.h"
37#include "r420_reg_safe.h"
34 38
35int r420_mc_init(struct radeon_device *rdev) 39static void r420_set_reg_safe(struct radeon_device *rdev)
36{ 40{
37 int r; 41 rdev->config.r300.reg_safe_bm = r420_reg_safe_bm;
38 42 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm);
39 /* Setup GPU memory space */
40 rdev->mc.vram_location = 0xFFFFFFFFUL;
41 rdev->mc.gtt_location = 0xFFFFFFFFUL;
42 if (rdev->flags & RADEON_IS_AGP) {
43 r = radeon_agp_init(rdev);
44 if (r) {
45 printk(KERN_WARNING "[drm] Disabling AGP\n");
46 rdev->flags &= ~RADEON_IS_AGP;
47 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
48 } else {
49 rdev->mc.gtt_location = rdev->mc.agp_base;
50 }
51 }
52 r = radeon_mc_setup(rdev);
53 if (r) {
54 return r;
55 }
56 return 0;
57} 43}
58 44
59void r420_pipes_init(struct radeon_device *rdev) 45void r420_pipes_init(struct radeon_device *rdev)
@@ -63,7 +49,8 @@ void r420_pipes_init(struct radeon_device *rdev)
63 unsigned num_pipes; 49 unsigned num_pipes;
64 50
65 /* GA_ENHANCE workaround TCL deadlock issue */ 51 /* GA_ENHANCE workaround TCL deadlock issue */
66 WREG32(0x4274, (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)); 52 WREG32(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL |
53 (1 << 2) | (1 << 3));
67 /* add idle wait as per freedesktop.org bug 24041 */ 54 /* add idle wait as per freedesktop.org bug 24041 */
68 if (r100_gui_wait_for_idle(rdev)) { 55 if (r100_gui_wait_for_idle(rdev)) {
69 printk(KERN_WARNING "Failed to wait GUI idle while " 56 printk(KERN_WARNING "Failed to wait GUI idle while "
@@ -72,6 +59,12 @@ void r420_pipes_init(struct radeon_device *rdev)
72 /* get max number of pipes */ 59 /* get max number of pipes */
73 gb_pipe_select = RREG32(0x402C); 60 gb_pipe_select = RREG32(0x402C);
74 num_pipes = ((gb_pipe_select >> 12) & 3) + 1; 61 num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
62
63 /* SE chips have 1 pipe */
64 if ((rdev->pdev->device == 0x5e4c) ||
65 (rdev->pdev->device == 0x5e4f))
66 num_pipes = 1;
67
75 rdev->num_gb_pipes = num_pipes; 68 rdev->num_gb_pipes = num_pipes;
76 tmp = 0; 69 tmp = 0;
77 switch (num_pipes) { 70 switch (num_pipes) {
@@ -91,17 +84,17 @@ void r420_pipes_init(struct radeon_device *rdev)
91 tmp = (7 << 1); 84 tmp = (7 << 1);
92 break; 85 break;
93 } 86 }
94 WREG32(0x42C8, (1 << num_pipes) - 1); 87 WREG32(R500_SU_REG_DEST, (1 << num_pipes) - 1);
95 /* Sub pixel 1/12 so we can have 4K rendering according to doc */ 88 /* Sub pixel 1/12 so we can have 4K rendering according to doc */
96 tmp |= (1 << 4) | (1 << 0); 89 tmp |= R300_TILE_SIZE_16 | R300_ENABLE_TILING;
97 WREG32(0x4018, tmp); 90 WREG32(R300_GB_TILE_CONFIG, tmp);
98 if (r100_gui_wait_for_idle(rdev)) { 91 if (r100_gui_wait_for_idle(rdev)) {
99 printk(KERN_WARNING "Failed to wait GUI idle while " 92 printk(KERN_WARNING "Failed to wait GUI idle while "
100 "programming pipes. Bad things might happen.\n"); 93 "programming pipes. Bad things might happen.\n");
101 } 94 }
102 95
103 tmp = RREG32(0x170C); 96 tmp = RREG32(R300_DST_PIPE_CONFIG);
104 WREG32(0x170C, tmp | (1 << 31)); 97 WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG);
105 98
106 WREG32(R300_RB2D_DSTCACHE_MODE, 99 WREG32(R300_RB2D_DSTCACHE_MODE,
107 RREG32(R300_RB2D_DSTCACHE_MODE) | 100 RREG32(R300_RB2D_DSTCACHE_MODE) |
@@ -165,10 +158,41 @@ static void r420_clock_resume(struct radeon_device *rdev)
165 WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl); 158 WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl);
166} 159}
167 160
161static void r420_cp_errata_init(struct radeon_device *rdev)
162{
163 /* RV410 and R420 can lock up if CP DMA to host memory happens
164 * while the 2D engine is busy.
165 *
166 * The proper workaround is to queue a RESYNC at the beginning
167 * of the CP init, apparently.
168 */
169 radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch);
170 radeon_ring_lock(rdev, 8);
171 radeon_ring_write(rdev, PACKET0(R300_CP_RESYNC_ADDR, 1));
172 radeon_ring_write(rdev, rdev->config.r300.resync_scratch);
173 radeon_ring_write(rdev, 0xDEADBEEF);
174 radeon_ring_unlock_commit(rdev);
175}
176
177static void r420_cp_errata_fini(struct radeon_device *rdev)
178{
179 /* Catch the RESYNC we dispatched all the way back,
180 * at the very beginning of the CP init.
181 */
182 radeon_ring_lock(rdev, 8);
183 radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
184 radeon_ring_write(rdev, R300_RB3D_DC_FINISH);
185 radeon_ring_unlock_commit(rdev);
186 radeon_scratch_free(rdev, rdev->config.r300.resync_scratch);
187}
188
168static int r420_startup(struct radeon_device *rdev) 189static int r420_startup(struct radeon_device *rdev)
169{ 190{
170 int r; 191 int r;
171 192
193 /* set common regs */
194 r100_set_common_regs(rdev);
195 /* program mc */
172 r300_mc_program(rdev); 196 r300_mc_program(rdev);
173 /* Resume clock */ 197 /* Resume clock */
174 r420_clock_resume(rdev); 198 r420_clock_resume(rdev);
@@ -186,14 +210,15 @@ static int r420_startup(struct radeon_device *rdev)
186 } 210 }
187 r420_pipes_init(rdev); 211 r420_pipes_init(rdev);
188 /* Enable IRQ */ 212 /* Enable IRQ */
189 rdev->irq.sw_int = true;
190 r100_irq_set(rdev); 213 r100_irq_set(rdev);
214 rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
191 /* 1M ring buffer */ 215 /* 1M ring buffer */
192 r = r100_cp_init(rdev, 1024 * 1024); 216 r = r100_cp_init(rdev, 1024 * 1024);
193 if (r) { 217 if (r) {
194 dev_err(rdev->dev, "failled initializing CP (%d).\n", r); 218 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
195 return r; 219 return r;
196 } 220 }
221 r420_cp_errata_init(rdev);
197 r = r100_wb_init(rdev); 222 r = r100_wb_init(rdev);
198 if (r) { 223 if (r) {
199 dev_err(rdev->dev, "failled initializing WB (%d).\n", r); 224 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
@@ -229,12 +254,14 @@ int r420_resume(struct radeon_device *rdev)
229 } 254 }
230 /* Resume clock after posting */ 255 /* Resume clock after posting */
231 r420_clock_resume(rdev); 256 r420_clock_resume(rdev);
232 257 /* Initialize surface registers */
258 radeon_surface_init(rdev);
233 return r420_startup(rdev); 259 return r420_startup(rdev);
234} 260}
235 261
236int r420_suspend(struct radeon_device *rdev) 262int r420_suspend(struct radeon_device *rdev)
237{ 263{
264 r420_cp_errata_fini(rdev);
238 r100_cp_disable(rdev); 265 r100_cp_disable(rdev);
239 r100_wb_disable(rdev); 266 r100_wb_disable(rdev);
240 r100_irq_disable(rdev); 267 r100_irq_disable(rdev);
@@ -247,6 +274,7 @@ int r420_suspend(struct radeon_device *rdev)
247 274
248void r420_fini(struct radeon_device *rdev) 275void r420_fini(struct radeon_device *rdev)
249{ 276{
277 radeon_pm_fini(rdev);
250 r100_cp_fini(rdev); 278 r100_cp_fini(rdev);
251 r100_wb_fini(rdev); 279 r100_wb_fini(rdev);
252 r100_ib_fini(rdev); 280 r100_ib_fini(rdev);
@@ -258,7 +286,7 @@ void r420_fini(struct radeon_device *rdev)
258 radeon_agp_fini(rdev); 286 radeon_agp_fini(rdev);
259 radeon_irq_kms_fini(rdev); 287 radeon_irq_kms_fini(rdev);
260 radeon_fence_driver_fini(rdev); 288 radeon_fence_driver_fini(rdev);
261 radeon_object_fini(rdev); 289 radeon_bo_fini(rdev);
262 if (rdev->is_atom_bios) { 290 if (rdev->is_atom_bios) {
263 radeon_atombios_fini(rdev); 291 radeon_atombios_fini(rdev);
264 } else { 292 } else {
@@ -301,25 +329,22 @@ int r420_init(struct radeon_device *rdev)
301 RREG32(R_0007C0_CP_STAT)); 329 RREG32(R_0007C0_CP_STAT));
302 } 330 }
303 /* check if cards are posted or not */ 331 /* check if cards are posted or not */
304 if (!radeon_card_posted(rdev) && rdev->bios) { 332 if (radeon_boot_test_post_card(rdev) == false)
305 DRM_INFO("GPU not posted. posting now...\n"); 333 return -EINVAL;
306 if (rdev->is_atom_bios) { 334
307 atom_asic_init(rdev->mode_info.atom_context);
308 } else {
309 radeon_combios_asic_init(rdev->ddev);
310 }
311 }
312 /* Initialize clocks */ 335 /* Initialize clocks */
313 radeon_get_clock_info(rdev->ddev); 336 radeon_get_clock_info(rdev->ddev);
314 /* Initialize power management */ 337 /* Initialize power management */
315 radeon_pm_init(rdev); 338 radeon_pm_init(rdev);
316 /* Get vram informations */ 339 /* initialize AGP */
317 r300_vram_info(rdev); 340 if (rdev->flags & RADEON_IS_AGP) {
318 /* Initialize memory controller (also test AGP) */ 341 r = radeon_agp_init(rdev);
319 r = r420_mc_init(rdev); 342 if (r) {
320 if (r) { 343 radeon_agp_disable(rdev);
321 return r; 344 }
322 } 345 }
346 /* initialize memory controller */
347 r300_mc_init(rdev);
323 r420_debugfs(rdev); 348 r420_debugfs(rdev);
324 /* Fence driver */ 349 /* Fence driver */
325 r = radeon_fence_driver_init(rdev); 350 r = radeon_fence_driver_init(rdev);
@@ -331,10 +356,13 @@ int r420_init(struct radeon_device *rdev)
331 return r; 356 return r;
332 } 357 }
333 /* Memory manager */ 358 /* Memory manager */
334 r = radeon_object_init(rdev); 359 r = radeon_bo_init(rdev);
335 if (r) { 360 if (r) {
336 return r; 361 return r;
337 } 362 }
363 if (rdev->family == CHIP_R420)
364 r100_enable_bm(rdev);
365
338 if (rdev->flags & RADEON_IS_PCIE) { 366 if (rdev->flags & RADEON_IS_PCIE) {
339 r = rv370_pcie_gart_init(rdev); 367 r = rv370_pcie_gart_init(rdev);
340 if (r) 368 if (r)
@@ -345,22 +373,21 @@ int r420_init(struct radeon_device *rdev)
345 if (r) 373 if (r)
346 return r; 374 return r;
347 } 375 }
348 r300_set_reg_safe(rdev); 376 r420_set_reg_safe(rdev);
349 rdev->accel_working = true; 377 rdev->accel_working = true;
350 r = r420_startup(rdev); 378 r = r420_startup(rdev);
351 if (r) { 379 if (r) {
352 /* Somethings want wront with the accel init stop accel */ 380 /* Somethings want wront with the accel init stop accel */
353 dev_err(rdev->dev, "Disabling GPU acceleration\n"); 381 dev_err(rdev->dev, "Disabling GPU acceleration\n");
354 r420_suspend(rdev);
355 r100_cp_fini(rdev); 382 r100_cp_fini(rdev);
356 r100_wb_fini(rdev); 383 r100_wb_fini(rdev);
357 r100_ib_fini(rdev); 384 r100_ib_fini(rdev);
385 radeon_irq_kms_fini(rdev);
358 if (rdev->flags & RADEON_IS_PCIE) 386 if (rdev->flags & RADEON_IS_PCIE)
359 rv370_pcie_gart_fini(rdev); 387 rv370_pcie_gart_fini(rdev);
360 if (rdev->flags & RADEON_IS_PCI) 388 if (rdev->flags & RADEON_IS_PCI)
361 r100_pci_gart_fini(rdev); 389 r100_pci_gart_fini(rdev);
362 radeon_agp_fini(rdev); 390 radeon_agp_fini(rdev);
363 radeon_irq_kms_fini(rdev);
364 rdev->accel_working = false; 391 rdev->accel_working = false;
365 } 392 }
366 return 0; 393 return 0;