diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 135 |
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 | ||
770 | void 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 | |||
2966 | int 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 | |||
3006 | void 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 | |||
3013 | int 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 | } | ||