aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r100.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-09-07 20:10:24 -0400
committerDave Airlie <airlied@redhat.com>2009-09-07 21:15:52 -0400
commit3ce0a23d2d253185df24e22e3d5f89800bb3dd1c (patch)
tree4b4defdbe33aec7317101cce0f89c33083f8d17b /drivers/gpu/drm/radeon/r100.c
parent4ce001abafafe77e5dd943d1480fc9f87894e96f (diff)
drm/radeon/kms: add r600 KMS support
This adds the r600 KMS + CS support to the Linux kernel. The r600 TTM support is quite basic and still needs more work esp around using interrupts, but the polled fencing should work okay for now. Also currently TTM is using memcpy to do VRAM moves, the code is here to use a 3D blit to do this, but isn't fully debugged yet. Authors: Alex Deucher <alexdeucher@gmail.com> Dave Airlie <airlied@redhat.com> Jerome Glisse <jglisse@redhat.com> Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r--drivers/gpu/drm/radeon/r100.c135
1 files changed, 123 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index ee3ab62417e2..5708c07ce733 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -31,6 +31,8 @@
31#include "radeon_drm.h" 31#include "radeon_drm.h"
32#include "radeon_reg.h" 32#include "radeon_reg.h"
33#include "radeon.h" 33#include "radeon.h"
34#include "r100d.h"
35
34#include <linux/firmware.h> 36#include <linux/firmware.h>
35#include <linux/platform_device.h> 37#include <linux/platform_device.h>
36 38
@@ -391,9 +393,9 @@ int r100_wb_init(struct radeon_device *rdev)
391 return r; 393 return r;
392 } 394 }
393 } 395 }
394 WREG32(0x774, rdev->wb.gpu_addr); 396 WREG32(RADEON_SCRATCH_ADDR, rdev->wb.gpu_addr);
395 WREG32(0x70C, rdev->wb.gpu_addr + 1024); 397 WREG32(RADEON_CP_RB_RPTR_ADDR, rdev->wb.gpu_addr + 1024);
396 WREG32(0x770, 0xff); 398 WREG32(RADEON_SCRATCH_UMSK, 0xff);
397 return 0; 399 return 0;
398} 400}
399 401
@@ -559,18 +561,18 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
559 fw_name = FIRMWARE_R520; 561 fw_name = FIRMWARE_R520;
560 } 562 }
561 563
562 err = request_firmware(&rdev->fw, fw_name, &pdev->dev); 564 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
563 platform_device_unregister(pdev); 565 platform_device_unregister(pdev);
564 if (err) { 566 if (err) {
565 printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", 567 printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
566 fw_name); 568 fw_name);
567 } else if (rdev->fw->size % 8) { 569 } else if (rdev->me_fw->size % 8) {
568 printk(KERN_ERR 570 printk(KERN_ERR
569 "radeon_cp: Bogus length %zu in firmware \"%s\"\n", 571 "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
570 rdev->fw->size, fw_name); 572 rdev->me_fw->size, fw_name);
571 err = -EINVAL; 573 err = -EINVAL;
572 release_firmware(rdev->fw); 574 release_firmware(rdev->me_fw);
573 rdev->fw = NULL; 575 rdev->me_fw = NULL;
574 } 576 }
575 return err; 577 return err;
576} 578}
@@ -584,9 +586,9 @@ static void r100_cp_load_microcode(struct radeon_device *rdev)
584 "programming pipes. Bad things might happen.\n"); 586 "programming pipes. Bad things might happen.\n");
585 } 587 }
586 588
587 if (rdev->fw) { 589 if (rdev->me_fw) {
588 size = rdev->fw->size / 4; 590 size = rdev->me_fw->size / 4;
589 fw_data = (const __be32 *)&rdev->fw->data[0]; 591 fw_data = (const __be32 *)&rdev->me_fw->data[0];
590 WREG32(RADEON_CP_ME_RAM_ADDR, 0); 592 WREG32(RADEON_CP_ME_RAM_ADDR, 0);
591 for (i = 0; i < size; i += 2) { 593 for (i = 0; i < size; i += 2) {
592 WREG32(RADEON_CP_ME_RAM_DATAH, 594 WREG32(RADEON_CP_ME_RAM_DATAH,
@@ -632,7 +634,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
632 DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); 634 DRM_INFO("radeon: cp idle (0x%08X)\n", tmp);
633 } 635 }
634 636
635 if (!rdev->fw) { 637 if (!rdev->me_fw) {
636 r = r100_cp_init_microcode(rdev); 638 r = r100_cp_init_microcode(rdev);
637 if (r) { 639 if (r) {
638 DRM_ERROR("Failed to load firmware!\n"); 640 DRM_ERROR("Failed to load firmware!\n");
@@ -765,6 +767,12 @@ int r100_cp_reset(struct radeon_device *rdev)
765 return -1; 767 return -1;
766} 768}
767 769
770void r100_cp_commit(struct radeon_device *rdev)
771{
772 WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
773 (void)RREG32(RADEON_CP_RB_WPTR);
774}
775
768 776
769/* 777/*
770 * CS functions 778 * CS functions
@@ -2954,3 +2962,106 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
2954 } 2962 }
2955 } 2963 }
2956} 2964}
2965
2966int r100_ring_test(struct radeon_device *rdev)
2967{
2968 uint32_t scratch;
2969 uint32_t tmp = 0;
2970 unsigned i;
2971 int r;
2972
2973 r = radeon_scratch_get(rdev, &scratch);
2974 if (r) {
2975 DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
2976 return r;
2977 }
2978 WREG32(scratch, 0xCAFEDEAD);
2979 r = radeon_ring_lock(rdev, 2);
2980 if (r) {
2981 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
2982 radeon_scratch_free(rdev, scratch);
2983 return r;
2984 }
2985 radeon_ring_write(rdev, PACKET0(scratch, 0));
2986 radeon_ring_write(rdev, 0xDEADBEEF);
2987 radeon_ring_unlock_commit(rdev);
2988 for (i = 0; i < rdev->usec_timeout; i++) {
2989 tmp = RREG32(scratch);
2990 if (tmp == 0xDEADBEEF) {
2991 break;
2992 }
2993 DRM_UDELAY(1);
2994 }
2995 if (i < rdev->usec_timeout) {
2996 DRM_INFO("ring test succeeded in %d usecs\n", i);
2997 } else {
2998 DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n",
2999 scratch, tmp);
3000 r = -EINVAL;
3001 }
3002 radeon_scratch_free(rdev, scratch);
3003 return r;
3004}
3005
3006void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3007{
3008 radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1));
3009 radeon_ring_write(rdev, ib->gpu_addr);
3010 radeon_ring_write(rdev, ib->length_dw);
3011}
3012
3013int r100_ib_test(struct radeon_device *rdev)
3014{
3015 struct radeon_ib *ib;
3016 uint32_t scratch;
3017 uint32_t tmp = 0;
3018 unsigned i;
3019 int r;
3020
3021 r = radeon_scratch_get(rdev, &scratch);
3022 if (r) {
3023 DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
3024 return r;
3025 }
3026 WREG32(scratch, 0xCAFEDEAD);
3027 r = radeon_ib_get(rdev, &ib);
3028 if (r) {
3029 return r;
3030 }
3031 ib->ptr[0] = PACKET0(scratch, 0);
3032 ib->ptr[1] = 0xDEADBEEF;
3033 ib->ptr[2] = PACKET2(0);
3034 ib->ptr[3] = PACKET2(0);
3035 ib->ptr[4] = PACKET2(0);
3036 ib->ptr[5] = PACKET2(0);
3037 ib->ptr[6] = PACKET2(0);
3038 ib->ptr[7] = PACKET2(0);
3039 ib->length_dw = 8;
3040 r = radeon_ib_schedule(rdev, ib);
3041 if (r) {
3042 radeon_scratch_free(rdev, scratch);
3043 radeon_ib_free(rdev, &ib);
3044 return r;
3045 }
3046 r = radeon_fence_wait(ib->fence, false);
3047 if (r) {
3048 return r;
3049 }
3050 for (i = 0; i < rdev->usec_timeout; i++) {
3051 tmp = RREG32(scratch);
3052 if (tmp == 0xDEADBEEF) {
3053 break;
3054 }
3055 DRM_UDELAY(1);
3056 }
3057 if (i < rdev->usec_timeout) {
3058 DRM_INFO("ib test succeeded in %u usecs\n", i);
3059 } else {
3060 DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
3061 scratch, tmp);
3062 r = -EINVAL;
3063 }
3064 radeon_scratch_free(rdev, scratch);
3065 radeon_ib_free(rdev, &ib);
3066 return r;
3067}