aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/rs400.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-10-01 04:20:52 -0400
committerDave Airlie <airlied@redhat.com>2009-10-01 18:51:46 -0400
commitca6ffc64cba0cdd0a2b3fcad0e1d19edcf277ccc (patch)
tree261529acbc21be0d7824770aca8e002f9765cc71 /drivers/gpu/drm/radeon/rs400.c
parentf0ed1f655aa0375e2abba84cc4e8e6c853d48555 (diff)
drm/radeon/kms: Convert RS400/RS480 to new init path & fix legacy VGA (V3)
Also cleanup register specific to RS400/RS480. This patch also fix legacy VGA register used to disable VGA access we were programming wrong register. Now we should properly disable VGA on r100 up to rs400 asics. Note that RS400/RS480 resume is broken, it hangs the computer while reprogramming dynamic clock, doesn't work either without that patch. We need to spend more time investigating this issue. Version 2 of the patch remove dead code that was left commented out in the previous version. Version 3 correct the placement on IGP of the VRAM inside GPU address space to match the stollen RAM placement of IGP. Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/rs400.c')
-rw-r--r--drivers/gpu/drm/radeon/rs400.c276
1 files changed, 190 insertions, 86 deletions
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index a3fbdad938c7..8b67605dbf3d 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -27,27 +27,12 @@
27 */ 27 */
28#include <linux/seq_file.h> 28#include <linux/seq_file.h>
29#include <drm/drmP.h> 29#include <drm/drmP.h>
30#include "radeon_reg.h"
31#include "radeon.h" 30#include "radeon.h"
31#include "rs400d.h"
32 32
33/* rs400,rs480 depends on : */ 33/* This files gather functions specifics to : rs400,rs480 */
34void r100_hdp_reset(struct radeon_device *rdev); 34static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
35void r100_mc_disable_clients(struct radeon_device *rdev);
36int r300_mc_wait_for_idle(struct radeon_device *rdev);
37void r420_pipes_init(struct radeon_device *rdev);
38 35
39/* This files gather functions specifics to :
40 * rs400,rs480
41 *
42 * Some of these functions might be used by newer ASICs.
43 */
44void rs400_gpu_init(struct radeon_device *rdev);
45int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
46
47
48/*
49 * GART functions.
50 */
51void rs400_gart_adjust_size(struct radeon_device *rdev) 36void rs400_gart_adjust_size(struct radeon_device *rdev)
52{ 37{
53 /* Check gart size */ 38 /* Check gart size */
@@ -238,61 +223,6 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
238 return 0; 223 return 0;
239} 224}
240 225
241
242/*
243 * MC functions.
244 */
245int rs400_mc_init(struct radeon_device *rdev)
246{
247 uint32_t tmp;
248 int r;
249
250 if (r100_debugfs_rbbm_init(rdev)) {
251 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
252 }
253
254 rs400_gpu_init(rdev);
255 rs400_gart_disable(rdev);
256 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
257 rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
258 rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
259 r = radeon_mc_setup(rdev);
260 if (r) {
261 return r;
262 }
263
264 r100_mc_disable_clients(rdev);
265 if (r300_mc_wait_for_idle(rdev)) {
266 printk(KERN_WARNING "Failed to wait MC idle while "
267 "programming pipes. Bad things might happen.\n");
268 }
269
270 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
271 tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
272 tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
273 WREG32(RADEON_MC_FB_LOCATION, tmp);
274 tmp = RREG32(RADEON_HOST_PATH_CNTL) | RADEON_HP_LIN_RD_CACHE_DIS;
275 WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
276 (void)RREG32(RADEON_HOST_PATH_CNTL);
277 WREG32(RADEON_HOST_PATH_CNTL, tmp);
278 (void)RREG32(RADEON_HOST_PATH_CNTL);
279
280 return 0;
281}
282
283void rs400_mc_fini(struct radeon_device *rdev)
284{
285}
286
287
288/*
289 * Global GPU functions
290 */
291void rs400_errata(struct radeon_device *rdev)
292{
293 rdev->pll_errata = 0;
294}
295
296void rs400_gpu_init(struct radeon_device *rdev) 226void rs400_gpu_init(struct radeon_device *rdev)
297{ 227{
298 /* FIXME: HDP same place on rs400 ? */ 228 /* FIXME: HDP same place on rs400 ? */
@@ -305,10 +235,6 @@ void rs400_gpu_init(struct radeon_device *rdev)
305 } 235 }
306} 236}
307 237
308
309/*
310 * VRAM info.
311 */
312void rs400_vram_info(struct radeon_device *rdev) 238void rs400_vram_info(struct radeon_device *rdev)
313{ 239{
314 rs400_gart_adjust_size(rdev); 240 rs400_gart_adjust_size(rdev);
@@ -319,10 +245,6 @@ void rs400_vram_info(struct radeon_device *rdev)
319 r100_vram_init_sizes(rdev); 245 r100_vram_init_sizes(rdev);
320} 246}
321 247
322
323/*
324 * Indirect registers accessor
325 */
326uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg) 248uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
327{ 249{
328 uint32_t r; 250 uint32_t r;
@@ -340,10 +262,6 @@ void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
340 WREG32(RS480_NB_MC_INDEX, 0xff); 262 WREG32(RS480_NB_MC_INDEX, 0xff);
341} 263}
342 264
343
344/*
345 * Debugfs info
346 */
347#if defined(CONFIG_DEBUG_FS) 265#if defined(CONFIG_DEBUG_FS)
348static int rs400_debugfs_gart_info(struct seq_file *m, void *data) 266static int rs400_debugfs_gart_info(struct seq_file *m, void *data)
349{ 267{
@@ -419,7 +337,7 @@ static struct drm_info_list rs400_gart_info_list[] = {
419}; 337};
420#endif 338#endif
421 339
422int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev) 340static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
423{ 341{
424#if defined(CONFIG_DEBUG_FS) 342#if defined(CONFIG_DEBUG_FS)
425 return radeon_debugfs_add_files(rdev, rs400_gart_info_list, 1); 343 return radeon_debugfs_add_files(rdev, rs400_gart_info_list, 1);
@@ -427,3 +345,189 @@ int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
427 return 0; 345 return 0;
428#endif 346#endif
429} 347}
348
349static int rs400_mc_init(struct radeon_device *rdev)
350{
351 int r;
352 u32 tmp;
353
354 /* Setup GPU memory space */
355 tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
356 rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
357 rdev->mc.gtt_location = 0xFFFFFFFFUL;
358 r = radeon_mc_setup(rdev);
359 if (r)
360 return r;
361 return 0;
362}
363
364void rs400_mc_program(struct radeon_device *rdev)
365{
366 struct r100_mc_save save;
367
368 /* Stops all mc clients */
369 r100_mc_stop(rdev, &save);
370
371 /* Wait for mc idle */
372 if (r300_mc_wait_for_idle(rdev))
373 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
374 WREG32(R_000148_MC_FB_LOCATION,
375 S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
376 S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
377
378 r100_mc_resume(rdev, &save);
379}
380
381static int rs400_startup(struct radeon_device *rdev)
382{
383 int r;
384
385 rs400_mc_program(rdev);
386 /* Resume clock */
387 r300_clock_startup(rdev);
388 /* Initialize GPU configuration (# pipes, ...) */
389 rs400_gpu_init(rdev);
390 /* Initialize GART (initialize after TTM so we can allocate
391 * memory through TTM but finalize after TTM) */
392 r = rs400_gart_enable(rdev);
393 if (r)
394 return r;
395 /* Enable IRQ */
396 rdev->irq.sw_int = true;
397 r100_irq_set(rdev);
398 /* 1M ring buffer */
399 r = r100_cp_init(rdev, 1024 * 1024);
400 if (r) {
401 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
402 return r;
403 }
404 r = r100_wb_init(rdev);
405 if (r)
406 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
407 r = r100_ib_init(rdev);
408 if (r) {
409 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
410 return r;
411 }
412 return 0;
413}
414
415int rs400_resume(struct radeon_device *rdev)
416{
417 /* Make sur GART are not working */
418 rs400_gart_disable(rdev);
419 /* Resume clock before doing reset */
420 r300_clock_startup(rdev);
421 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
422 if (radeon_gpu_reset(rdev)) {
423 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
424 RREG32(R_000E40_RBBM_STATUS),
425 RREG32(R_0007C0_CP_STAT));
426 }
427 /* post */
428 radeon_combios_asic_init(rdev->ddev);
429 /* Resume clock after posting */
430 r300_clock_startup(rdev);
431 return rs400_startup(rdev);
432}
433
434int rs400_suspend(struct radeon_device *rdev)
435{
436 r100_cp_disable(rdev);
437 r100_wb_disable(rdev);
438 r100_irq_disable(rdev);
439 rs400_gart_disable(rdev);
440 return 0;
441}
442
443void rs400_fini(struct radeon_device *rdev)
444{
445 rs400_suspend(rdev);
446 r100_cp_fini(rdev);
447 r100_wb_fini(rdev);
448 r100_ib_fini(rdev);
449 radeon_gem_fini(rdev);
450 rs400_gart_fini(rdev);
451 radeon_irq_kms_fini(rdev);
452 radeon_fence_driver_fini(rdev);
453 radeon_object_fini(rdev);
454 radeon_atombios_fini(rdev);
455 kfree(rdev->bios);
456 rdev->bios = NULL;
457}
458
459int rs400_init(struct radeon_device *rdev)
460{
461 int r;
462
463 rdev->new_init_path = true;
464 /* Disable VGA */
465 r100_vga_render_disable(rdev);
466 /* Initialize scratch registers */
467 radeon_scratch_init(rdev);
468 /* Initialize surface registers */
469 radeon_surface_init(rdev);
470 /* TODO: disable VGA need to use VGA request */
471 /* BIOS*/
472 if (!radeon_get_bios(rdev)) {
473 if (ASIC_IS_AVIVO(rdev))
474 return -EINVAL;
475 }
476 if (rdev->is_atom_bios) {
477 dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
478 return -EINVAL;
479 } else {
480 r = radeon_combios_init(rdev);
481 if (r)
482 return r;
483 }
484 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
485 if (radeon_gpu_reset(rdev)) {
486 dev_warn(rdev->dev,
487 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
488 RREG32(R_000E40_RBBM_STATUS),
489 RREG32(R_0007C0_CP_STAT));
490 }
491 /* check if cards are posted or not */
492 if (!radeon_card_posted(rdev) && rdev->bios) {
493 DRM_INFO("GPU not posted. posting now...\n");
494 radeon_combios_asic_init(rdev->ddev);
495 }
496 /* Initialize clocks */
497 radeon_get_clock_info(rdev->ddev);
498 /* Get vram informations */
499 rs400_vram_info(rdev);
500 /* Initialize memory controller (also test AGP) */
501 r = rs400_mc_init(rdev);
502 if (r)
503 return r;
504 /* Fence driver */
505 r = radeon_fence_driver_init(rdev);
506 if (r)
507 return r;
508 r = radeon_irq_kms_init(rdev);
509 if (r)
510 return r;
511 /* Memory manager */
512 r = radeon_object_init(rdev);
513 if (r)
514 return r;
515 r = rs400_gart_init(rdev);
516 if (r)
517 return r;
518 r300_set_reg_safe(rdev);
519 rdev->accel_working = true;
520 r = rs400_startup(rdev);
521 if (r) {
522 /* Somethings want wront with the accel init stop accel */
523 dev_err(rdev->dev, "Disabling GPU acceleration\n");
524 rs400_suspend(rdev);
525 r100_cp_fini(rdev);
526 r100_wb_fini(rdev);
527 r100_ib_fini(rdev);
528 rs400_gart_fini(rdev);
529 radeon_irq_kms_fini(rdev);
530 rdev->accel_working = false;
531 }
532 return 0;
533}