diff options
Diffstat (limited to 'drivers')
33 files changed, 8289 insertions, 606 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index c5db0c4fe788..14c3fe692723 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -46,8 +46,9 @@ radeon-$(CONFIG_DRM_RADEON_KMS) += radeon_device.o radeon_kms.o \ | |||
46 | radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \ | 46 | radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \ |
47 | radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \ | 47 | radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \ |
48 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ | 48 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ |
49 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \ | 49 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
50 | radeon_test.o r200.o radeon_legacy_tv.o | 50 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ |
51 | r600_blit_kms.o | ||
51 | 52 | ||
52 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 53 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
53 | 54 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 8e31e992ec53..a7edd0f2ac37 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -389,6 +389,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
389 | pll_flags |= RADEON_PLL_USE_REF_DIV; | 389 | pll_flags |= RADEON_PLL_USE_REF_DIV; |
390 | } | 390 | } |
391 | radeon_encoder = to_radeon_encoder(encoder); | 391 | radeon_encoder = to_radeon_encoder(encoder); |
392 | break; | ||
392 | } | 393 | } |
393 | } | 394 | } |
394 | 395 | ||
diff --git a/drivers/gpu/drm/radeon/r300.h b/drivers/gpu/drm/radeon/avivod.h index 8486b4da9d69..d4e6e6e4a938 100644 --- a/drivers/gpu/drm/radeon/r300.h +++ b/drivers/gpu/drm/radeon/avivod.h | |||
@@ -1,7 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2008 Advanced Micro Devices, Inc. | 2 | * Copyright 2009 Advanced Micro Devices, Inc. |
3 | * Copyright 2008 Red Hat Inc. | 3 | * Copyright 2009 Red Hat Inc. |
4 | * Copyright 2009 Jerome Glisse. | ||
5 | * | 4 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | 5 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the "Software"), | 6 | * copy of this software and associated documentation files (the "Software"), |
@@ -25,12 +24,37 @@ | |||
25 | * Alex Deucher | 24 | * Alex Deucher |
26 | * Jerome Glisse | 25 | * Jerome Glisse |
27 | */ | 26 | */ |
28 | #ifndef R300_H | 27 | #ifndef AVIVOD_H |
29 | #define R300_H | 28 | #define AVIVOD_H |
30 | 29 | ||
31 | struct r300_asic { | 30 | |
32 | const unsigned *reg_safe_bm; | 31 | #define D1CRTC_CONTROL 0x6080 |
33 | unsigned reg_safe_bm_size; | 32 | #define CRTC_EN (1 << 0) |
34 | }; | 33 | #define D1CRTC_UPDATE_LOCK 0x60E8 |
34 | #define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 | ||
35 | #define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 | ||
36 | |||
37 | #define D2CRTC_CONTROL 0x6880 | ||
38 | #define D2CRTC_UPDATE_LOCK 0x68E8 | ||
39 | #define D2GRPH_PRIMARY_SURFACE_ADDRESS 0x6910 | ||
40 | #define D2GRPH_SECONDARY_SURFACE_ADDRESS 0x6918 | ||
41 | |||
42 | #define D1VGA_CONTROL 0x0330 | ||
43 | #define DVGA_CONTROL_MODE_ENABLE (1 << 0) | ||
44 | #define DVGA_CONTROL_TIMING_SELECT (1 << 8) | ||
45 | #define DVGA_CONTROL_SYNC_POLARITY_SELECT (1 << 9) | ||
46 | #define DVGA_CONTROL_OVERSCAN_TIMING_SELECT (1 << 10) | ||
47 | #define DVGA_CONTROL_OVERSCAN_COLOR_EN (1 << 16) | ||
48 | #define DVGA_CONTROL_ROTATE (1 << 24) | ||
49 | #define D2VGA_CONTROL 0x0338 | ||
50 | |||
51 | #define VGA_HDP_CONTROL 0x328 | ||
52 | #define VGA_MEM_PAGE_SELECT_EN (1 << 0) | ||
53 | #define VGA_MEMORY_DISABLE (1 << 4) | ||
54 | #define VGA_RBBM_LOCK_DISABLE (1 << 8) | ||
55 | #define VGA_SOFT_RESET (1 << 16) | ||
56 | #define VGA_MEMORY_BASE_ADDRESS 0x0310 | ||
57 | #define VGA_RENDER_CONTROL 0x0300 | ||
58 | #define VGA_VSTATUS_CNTL_MASK 0x00030000 | ||
35 | 59 | ||
36 | #endif | 60 | #endif |
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 | } | ||
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h new file mode 100644 index 000000000000..6da7d92c321c --- /dev/null +++ b/drivers/gpu/drm/radeon/r100d.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * Copyright 2009 Jerome Glisse. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: Dave Airlie | ||
25 | * Alex Deucher | ||
26 | * Jerome Glisse | ||
27 | */ | ||
28 | #ifndef __R100D_H__ | ||
29 | #define __R100D_H__ | ||
30 | |||
31 | #define CP_PACKET0 0x00000000 | ||
32 | #define PACKET0_BASE_INDEX_SHIFT 0 | ||
33 | #define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) | ||
34 | #define PACKET0_COUNT_SHIFT 16 | ||
35 | #define PACKET0_COUNT_MASK (0x3fff << 16) | ||
36 | #define CP_PACKET1 0x40000000 | ||
37 | #define CP_PACKET2 0x80000000 | ||
38 | #define PACKET2_PAD_SHIFT 0 | ||
39 | #define PACKET2_PAD_MASK (0x3fffffff << 0) | ||
40 | #define CP_PACKET3 0xC0000000 | ||
41 | #define PACKET3_IT_OPCODE_SHIFT 8 | ||
42 | #define PACKET3_IT_OPCODE_MASK (0xff << 8) | ||
43 | #define PACKET3_COUNT_SHIFT 16 | ||
44 | #define PACKET3_COUNT_MASK (0x3fff << 16) | ||
45 | /* PACKET3 op code */ | ||
46 | #define PACKET3_NOP 0x10 | ||
47 | #define PACKET3_3D_DRAW_VBUF 0x28 | ||
48 | #define PACKET3_3D_DRAW_IMMD 0x29 | ||
49 | #define PACKET3_3D_DRAW_INDX 0x2A | ||
50 | #define PACKET3_3D_LOAD_VBPNTR 0x2F | ||
51 | #define PACKET3_INDX_BUFFER 0x33 | ||
52 | #define PACKET3_3D_DRAW_VBUF_2 0x34 | ||
53 | #define PACKET3_3D_DRAW_IMMD_2 0x35 | ||
54 | #define PACKET3_3D_DRAW_INDX_2 0x36 | ||
55 | #define PACKET3_BITBLT_MULTI 0x9B | ||
56 | |||
57 | #define PACKET0(reg, n) (CP_PACKET0 | \ | ||
58 | REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ | ||
59 | REG_SET(PACKET0_COUNT, (n))) | ||
60 | #define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) | ||
61 | #define PACKET3(op, n) (CP_PACKET3 | \ | ||
62 | REG_SET(PACKET3_IT_OPCODE, (op)) | \ | ||
63 | REG_SET(PACKET3_COUNT, (n))) | ||
64 | |||
65 | #define PACKET_TYPE0 0 | ||
66 | #define PACKET_TYPE1 1 | ||
67 | #define PACKET_TYPE2 2 | ||
68 | #define PACKET_TYPE3 3 | ||
69 | |||
70 | #define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) | ||
71 | #define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) | ||
72 | #define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) | ||
73 | #define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) | ||
74 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | ||
75 | |||
76 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 33a2c557eac4..a5f82f7beed6 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "radeon_drm.h" | 33 | #include "radeon_drm.h" |
34 | #include "radeon_share.h" | 34 | #include "radeon_share.h" |
35 | #include "r100_track.h" | 35 | #include "r100_track.h" |
36 | #include "r300d.h" | ||
36 | 37 | ||
37 | #include "r300_reg_safe.h" | 38 | #include "r300_reg_safe.h" |
38 | 39 | ||
@@ -127,7 +128,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) | |||
127 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); | 128 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); |
128 | rv370_pcie_gart_tlb_flush(rdev); | 129 | rv370_pcie_gart_tlb_flush(rdev); |
129 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%08X).\n", | 130 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%08X).\n", |
130 | rdev->mc.gtt_size >> 20, table_addr); | 131 | (unsigned)(rdev->mc.gtt_size >> 20), table_addr); |
131 | rdev->gart.ready = true; | 132 | rdev->gart.ready = true; |
132 | return 0; | 133 | return 0; |
133 | } | 134 | } |
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h new file mode 100644 index 000000000000..63ec076f2cd4 --- /dev/null +++ b/drivers/gpu/drm/radeon/r300d.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * Copyright 2009 Jerome Glisse. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: Dave Airlie | ||
25 | * Alex Deucher | ||
26 | * Jerome Glisse | ||
27 | */ | ||
28 | #ifndef __R300D_H__ | ||
29 | #define __R300D_H__ | ||
30 | |||
31 | #define CP_PACKET0 0x00000000 | ||
32 | #define PACKET0_BASE_INDEX_SHIFT 0 | ||
33 | #define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) | ||
34 | #define PACKET0_COUNT_SHIFT 16 | ||
35 | #define PACKET0_COUNT_MASK (0x3fff << 16) | ||
36 | #define CP_PACKET1 0x40000000 | ||
37 | #define CP_PACKET2 0x80000000 | ||
38 | #define PACKET2_PAD_SHIFT 0 | ||
39 | #define PACKET2_PAD_MASK (0x3fffffff << 0) | ||
40 | #define CP_PACKET3 0xC0000000 | ||
41 | #define PACKET3_IT_OPCODE_SHIFT 8 | ||
42 | #define PACKET3_IT_OPCODE_MASK (0xff << 8) | ||
43 | #define PACKET3_COUNT_SHIFT 16 | ||
44 | #define PACKET3_COUNT_MASK (0x3fff << 16) | ||
45 | /* PACKET3 op code */ | ||
46 | #define PACKET3_NOP 0x10 | ||
47 | #define PACKET3_3D_DRAW_VBUF 0x28 | ||
48 | #define PACKET3_3D_DRAW_IMMD 0x29 | ||
49 | #define PACKET3_3D_DRAW_INDX 0x2A | ||
50 | #define PACKET3_3D_LOAD_VBPNTR 0x2F | ||
51 | #define PACKET3_INDX_BUFFER 0x33 | ||
52 | #define PACKET3_3D_DRAW_VBUF_2 0x34 | ||
53 | #define PACKET3_3D_DRAW_IMMD_2 0x35 | ||
54 | #define PACKET3_3D_DRAW_INDX_2 0x36 | ||
55 | #define PACKET3_BITBLT_MULTI 0x9B | ||
56 | |||
57 | #define PACKET0(reg, n) (CP_PACKET0 | \ | ||
58 | REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ | ||
59 | REG_SET(PACKET0_COUNT, (n))) | ||
60 | #define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) | ||
61 | #define PACKET3(op, n) (CP_PACKET3 | \ | ||
62 | REG_SET(PACKET3_IT_OPCODE, (op)) | \ | ||
63 | REG_SET(PACKET3_COUNT, (n))) | ||
64 | |||
65 | #define PACKET_TYPE0 0 | ||
66 | #define PACKET_TYPE1 1 | ||
67 | #define PACKET_TYPE2 2 | ||
68 | #define PACKET_TYPE3 3 | ||
69 | |||
70 | #define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) | ||
71 | #define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) | ||
72 | #define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) | ||
73 | #define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) | ||
74 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | ||
75 | |||
76 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 538cd907df69..d8fcef44a69f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -25,12 +25,46 @@ | |||
25 | * Alex Deucher | 25 | * Alex Deucher |
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #include <linux/seq_file.h> | ||
29 | #include <linux/firmware.h> | ||
30 | #include <linux/platform_device.h> | ||
28 | #include "drmP.h" | 31 | #include "drmP.h" |
29 | #include "radeon_reg.h" | 32 | #include "radeon_drm.h" |
30 | #include "radeon.h" | 33 | #include "radeon.h" |
34 | #include "radeon_mode.h" | ||
35 | #include "radeon_share.h" | ||
36 | #include "r600d.h" | ||
37 | #include "avivod.h" | ||
38 | #include "atom.h" | ||
31 | 39 | ||
32 | /* r600,rv610,rv630,rv620,rv635,rv670 depends on : */ | 40 | #define PFP_UCODE_SIZE 576 |
33 | void rs600_mc_disable_clients(struct radeon_device *rdev); | 41 | #define PM4_UCODE_SIZE 1792 |
42 | #define R700_PFP_UCODE_SIZE 848 | ||
43 | #define R700_PM4_UCODE_SIZE 1360 | ||
44 | |||
45 | /* Firmware Names */ | ||
46 | MODULE_FIRMWARE("radeon/R600_pfp.bin"); | ||
47 | MODULE_FIRMWARE("radeon/R600_me.bin"); | ||
48 | MODULE_FIRMWARE("radeon/RV610_pfp.bin"); | ||
49 | MODULE_FIRMWARE("radeon/RV610_me.bin"); | ||
50 | MODULE_FIRMWARE("radeon/RV630_pfp.bin"); | ||
51 | MODULE_FIRMWARE("radeon/RV630_me.bin"); | ||
52 | MODULE_FIRMWARE("radeon/RV620_pfp.bin"); | ||
53 | MODULE_FIRMWARE("radeon/RV620_me.bin"); | ||
54 | MODULE_FIRMWARE("radeon/RV635_pfp.bin"); | ||
55 | MODULE_FIRMWARE("radeon/RV635_me.bin"); | ||
56 | MODULE_FIRMWARE("radeon/RV670_pfp.bin"); | ||
57 | MODULE_FIRMWARE("radeon/RV670_me.bin"); | ||
58 | MODULE_FIRMWARE("radeon/RS780_pfp.bin"); | ||
59 | MODULE_FIRMWARE("radeon/RS780_me.bin"); | ||
60 | MODULE_FIRMWARE("radeon/RV770_pfp.bin"); | ||
61 | MODULE_FIRMWARE("radeon/RV770_me.bin"); | ||
62 | MODULE_FIRMWARE("radeon/RV730_pfp.bin"); | ||
63 | MODULE_FIRMWARE("radeon/RV730_me.bin"); | ||
64 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); | ||
65 | MODULE_FIRMWARE("radeon/RV710_me.bin"); | ||
66 | |||
67 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); | ||
34 | 68 | ||
35 | /* This files gather functions specifics to: | 69 | /* This files gather functions specifics to: |
36 | * r600,rv610,rv630,rv620,rv635,rv670 | 70 | * r600,rv610,rv630,rv620,rv635,rv670 |
@@ -39,87 +73,270 @@ void rs600_mc_disable_clients(struct radeon_device *rdev); | |||
39 | */ | 73 | */ |
40 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 74 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
41 | void r600_gpu_init(struct radeon_device *rdev); | 75 | void r600_gpu_init(struct radeon_device *rdev); |
76 | void r600_fini(struct radeon_device *rdev); | ||
42 | 77 | ||
43 | 78 | ||
44 | /* | 79 | /* |
45 | * MC | 80 | * R600 PCIE GART |
46 | */ | 81 | */ |
47 | int r600_mc_init(struct radeon_device *rdev) | 82 | int r600_gart_clear_page(struct radeon_device *rdev, int i) |
48 | { | 83 | { |
49 | uint32_t tmp; | 84 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; |
85 | u64 pte; | ||
50 | 86 | ||
51 | r600_gpu_init(rdev); | 87 | if (i < 0 || i > rdev->gart.num_gpu_pages) |
88 | return -EINVAL; | ||
89 | pte = 0; | ||
90 | writeq(pte, ((void __iomem *)ptr) + (i * 8)); | ||
91 | return 0; | ||
92 | } | ||
52 | 93 | ||
53 | /* setup the gart before changing location so we can ask to | 94 | void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) |
54 | * discard unmapped mc request | 95 | { |
55 | */ | 96 | unsigned i; |
56 | /* FIXME: disable out of gart access */ | 97 | u32 tmp; |
57 | tmp = rdev->mc.gtt_location / 4096; | 98 | |
58 | tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp); | 99 | WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); |
59 | WREG32(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp); | 100 | WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); |
60 | tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096; | 101 | WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); |
61 | tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp); | 102 | for (i = 0; i < rdev->usec_timeout; i++) { |
62 | WREG32(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp); | 103 | /* read MC_STATUS */ |
63 | 104 | tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE); | |
64 | rs600_mc_disable_clients(rdev); | 105 | tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT; |
65 | if (r600_mc_wait_for_idle(rdev)) { | 106 | if (tmp == 2) { |
66 | printk(KERN_WARNING "Failed to wait MC idle while " | 107 | printk(KERN_WARNING "[drm] r600 flush TLB failed\n"); |
67 | "programming pipes. Bad things might happen.\n"); | 108 | return; |
109 | } | ||
110 | if (tmp) { | ||
111 | return; | ||
112 | } | ||
113 | udelay(1); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | int r600_pcie_gart_enable(struct radeon_device *rdev) | ||
118 | { | ||
119 | u32 tmp; | ||
120 | int r, i; | ||
121 | |||
122 | /* Initialize common gart structure */ | ||
123 | r = radeon_gart_init(rdev); | ||
124 | if (r) { | ||
125 | return r; | ||
126 | } | ||
127 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; | ||
128 | r = radeon_gart_table_vram_alloc(rdev); | ||
129 | if (r) { | ||
130 | return r; | ||
68 | } | 131 | } |
132 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | ||
133 | r600_gart_clear_page(rdev, i); | ||
134 | /* Setup L2 cache */ | ||
135 | WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | | ||
136 | ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | | ||
137 | EFFECTIVE_L2_QUEUE_SIZE(7)); | ||
138 | WREG32(VM_L2_CNTL2, 0); | ||
139 | WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); | ||
140 | /* Setup TLB control */ | ||
141 | tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | | ||
142 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | | ||
143 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | | ||
144 | ENABLE_WAIT_L2_QUERY; | ||
145 | WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); | ||
146 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); | ||
147 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING); | ||
148 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); | ||
149 | WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); | ||
150 | WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); | ||
151 | WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); | ||
152 | WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); | ||
153 | WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); | ||
154 | WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); | ||
155 | WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); | ||
156 | WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); | ||
157 | WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); | ||
158 | WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); | ||
159 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | ||
160 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12); | ||
161 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | ||
162 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | ||
163 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | ||
164 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | ||
165 | (u32)(rdev->dummy_page.addr >> 12)); | ||
166 | for (i = 1; i < 7; i++) | ||
167 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | ||
69 | 168 | ||
70 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | 169 | r600_pcie_gart_tlb_flush(rdev); |
71 | tmp = REG_SET(R600_MC_FB_TOP, tmp >> 24); | 170 | rdev->gart.ready = true; |
72 | tmp |= REG_SET(R600_MC_FB_BASE, rdev->mc.vram_location >> 24); | ||
73 | WREG32(R600_MC_VM_FB_LOCATION, tmp); | ||
74 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | ||
75 | tmp = REG_SET(R600_MC_AGP_TOP, tmp >> 22); | ||
76 | WREG32(R600_MC_VM_AGP_TOP, tmp); | ||
77 | tmp = REG_SET(R600_MC_AGP_BOT, rdev->mc.gtt_location >> 22); | ||
78 | WREG32(R600_MC_VM_AGP_BOT, tmp); | ||
79 | return 0; | 171 | return 0; |
80 | } | 172 | } |
81 | 173 | ||
82 | void r600_mc_fini(struct radeon_device *rdev) | 174 | void r600_pcie_gart_disable(struct radeon_device *rdev) |
83 | { | 175 | { |
84 | /* FIXME: implement */ | 176 | u32 tmp; |
85 | } | 177 | int i; |
86 | 178 | ||
179 | /* Clear ptes*/ | ||
180 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | ||
181 | r600_gart_clear_page(rdev, i); | ||
182 | r600_pcie_gart_tlb_flush(rdev); | ||
183 | /* Disable all tables */ | ||
184 | for (i = 0; i < 7; i++) | ||
185 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | ||
87 | 186 | ||
88 | /* | 187 | /* Disable L2 cache */ |
89 | * Global GPU functions | 188 | WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | |
90 | */ | 189 | EFFECTIVE_L2_QUEUE_SIZE(7)); |
91 | void r600_errata(struct radeon_device *rdev) | 190 | WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); |
92 | { | 191 | /* Setup L1 TLB control */ |
93 | rdev->pll_errata = 0; | 192 | tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | |
193 | ENABLE_WAIT_L2_QUERY; | ||
194 | WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); | ||
195 | WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); | ||
196 | WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); | ||
197 | WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); | ||
198 | WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); | ||
199 | WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); | ||
200 | WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); | ||
201 | WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); | ||
202 | WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp); | ||
203 | WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp); | ||
204 | WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); | ||
205 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); | ||
206 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); | ||
207 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); | ||
94 | } | 208 | } |
95 | 209 | ||
96 | int r600_mc_wait_for_idle(struct radeon_device *rdev) | 210 | int r600_mc_wait_for_idle(struct radeon_device *rdev) |
97 | { | 211 | { |
98 | /* FIXME: implement */ | 212 | unsigned i; |
99 | return 0; | 213 | u32 tmp; |
214 | |||
215 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
216 | /* read MC_STATUS */ | ||
217 | tmp = RREG32(R_000E50_SRBM_STATUS) & 0x3F00; | ||
218 | if (!tmp) | ||
219 | return 0; | ||
220 | udelay(1); | ||
221 | } | ||
222 | return -1; | ||
100 | } | 223 | } |
101 | 224 | ||
102 | void r600_gpu_init(struct radeon_device *rdev) | 225 | static void r600_mc_resume(struct radeon_device *rdev) |
103 | { | 226 | { |
104 | /* FIXME: implement */ | 227 | u32 d1vga_control, d2vga_control; |
105 | } | 228 | u32 vga_render_control, vga_hdp_control; |
229 | u32 d1crtc_control, d2crtc_control; | ||
230 | u32 new_d1grph_primary, new_d1grph_secondary; | ||
231 | u32 new_d2grph_primary, new_d2grph_secondary; | ||
232 | u64 old_vram_start; | ||
233 | u32 tmp; | ||
234 | int i, j; | ||
106 | 235 | ||
236 | /* Initialize HDP */ | ||
237 | for (i = 0, j = 0; i < 32; i++, j += 0x18) { | ||
238 | WREG32((0x2c14 + j), 0x00000000); | ||
239 | WREG32((0x2c18 + j), 0x00000000); | ||
240 | WREG32((0x2c1c + j), 0x00000000); | ||
241 | WREG32((0x2c20 + j), 0x00000000); | ||
242 | WREG32((0x2c24 + j), 0x00000000); | ||
243 | } | ||
244 | WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); | ||
107 | 245 | ||
108 | /* | 246 | d1vga_control = RREG32(D1VGA_CONTROL); |
109 | * VRAM info | 247 | d2vga_control = RREG32(D2VGA_CONTROL); |
110 | */ | 248 | vga_render_control = RREG32(VGA_RENDER_CONTROL); |
111 | void r600_vram_get_type(struct radeon_device *rdev) | 249 | vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
250 | d1crtc_control = RREG32(D1CRTC_CONTROL); | ||
251 | d2crtc_control = RREG32(D2CRTC_CONTROL); | ||
252 | old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | ||
253 | new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS); | ||
254 | new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS); | ||
255 | new_d1grph_primary += rdev->mc.vram_start - old_vram_start; | ||
256 | new_d1grph_secondary += rdev->mc.vram_start - old_vram_start; | ||
257 | new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS); | ||
258 | new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS); | ||
259 | new_d2grph_primary += rdev->mc.vram_start - old_vram_start; | ||
260 | new_d2grph_secondary += rdev->mc.vram_start - old_vram_start; | ||
261 | |||
262 | /* Stop all video */ | ||
263 | WREG32(D1VGA_CONTROL, 0); | ||
264 | WREG32(D2VGA_CONTROL, 0); | ||
265 | WREG32(VGA_RENDER_CONTROL, 0); | ||
266 | WREG32(D1CRTC_UPDATE_LOCK, 1); | ||
267 | WREG32(D2CRTC_UPDATE_LOCK, 1); | ||
268 | WREG32(D1CRTC_CONTROL, 0); | ||
269 | WREG32(D2CRTC_CONTROL, 0); | ||
270 | WREG32(D1CRTC_UPDATE_LOCK, 0); | ||
271 | WREG32(D2CRTC_UPDATE_LOCK, 0); | ||
272 | |||
273 | mdelay(1); | ||
274 | if (r600_mc_wait_for_idle(rdev)) { | ||
275 | printk(KERN_WARNING "[drm] MC not idle !\n"); | ||
276 | } | ||
277 | |||
278 | /* Lockout access through VGA aperture*/ | ||
279 | WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); | ||
280 | |||
281 | /* Update configuration */ | ||
282 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); | ||
283 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); | ||
284 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | ||
285 | tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16; | ||
286 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | ||
287 | WREG32(MC_VM_FB_LOCATION, tmp); | ||
288 | WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); | ||
289 | WREG32(HDP_NONSURFACE_INFO, (2 << 7)); | ||
290 | WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); | ||
291 | if (rdev->flags & RADEON_IS_AGP) { | ||
292 | WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16); | ||
293 | WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); | ||
294 | WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); | ||
295 | } else { | ||
296 | WREG32(MC_VM_AGP_BASE, 0); | ||
297 | WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); | ||
298 | WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); | ||
299 | } | ||
300 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary); | ||
301 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary); | ||
302 | WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary); | ||
303 | WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary); | ||
304 | WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); | ||
305 | |||
306 | /* Unlock host access */ | ||
307 | WREG32(VGA_HDP_CONTROL, vga_hdp_control); | ||
308 | |||
309 | mdelay(1); | ||
310 | if (r600_mc_wait_for_idle(rdev)) { | ||
311 | printk(KERN_WARNING "[drm] MC not idle !\n"); | ||
312 | } | ||
313 | |||
314 | /* Restore video state */ | ||
315 | WREG32(D1CRTC_UPDATE_LOCK, 1); | ||
316 | WREG32(D2CRTC_UPDATE_LOCK, 1); | ||
317 | WREG32(D1CRTC_CONTROL, d1crtc_control); | ||
318 | WREG32(D2CRTC_CONTROL, d2crtc_control); | ||
319 | WREG32(D1CRTC_UPDATE_LOCK, 0); | ||
320 | WREG32(D2CRTC_UPDATE_LOCK, 0); | ||
321 | WREG32(D1VGA_CONTROL, d1vga_control); | ||
322 | WREG32(D2VGA_CONTROL, d2vga_control); | ||
323 | WREG32(VGA_RENDER_CONTROL, vga_render_control); | ||
324 | } | ||
325 | |||
326 | int r600_mc_init(struct radeon_device *rdev) | ||
112 | { | 327 | { |
113 | uint32_t tmp; | 328 | fixed20_12 a; |
329 | u32 tmp; | ||
114 | int chansize; | 330 | int chansize; |
331 | int r; | ||
115 | 332 | ||
333 | /* Get VRAM informations */ | ||
116 | rdev->mc.vram_width = 128; | 334 | rdev->mc.vram_width = 128; |
117 | rdev->mc.vram_is_ddr = true; | 335 | rdev->mc.vram_is_ddr = true; |
118 | 336 | tmp = RREG32(RAMCFG); | |
119 | tmp = RREG32(R600_RAMCFG); | 337 | if (tmp & CHANSIZE_OVERRIDE) { |
120 | if (tmp & R600_CHANSIZE_OVERRIDE) { | ||
121 | chansize = 16; | 338 | chansize = 16; |
122 | } else if (tmp & R600_CHANSIZE) { | 339 | } else if (tmp & CHANSIZE_MASK) { |
123 | chansize = 64; | 340 | chansize = 64; |
124 | } else { | 341 | } else { |
125 | chansize = 32; | 342 | chansize = 32; |
@@ -135,36 +352,1391 @@ void r600_vram_get_type(struct radeon_device *rdev) | |||
135 | (rdev->family == CHIP_RV635)) { | 352 | (rdev->family == CHIP_RV635)) { |
136 | rdev->mc.vram_width = 2 * chansize; | 353 | rdev->mc.vram_width = 2 * chansize; |
137 | } | 354 | } |
355 | /* Could aper size report 0 ? */ | ||
356 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | ||
357 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | ||
358 | /* Setup GPU memory space */ | ||
359 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | ||
360 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | ||
361 | if (rdev->flags & RADEON_IS_AGP) { | ||
362 | r = radeon_agp_init(rdev); | ||
363 | if (r) | ||
364 | return r; | ||
365 | /* gtt_size is setup by radeon_agp_init */ | ||
366 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
367 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; | ||
368 | /* Try to put vram before or after AGP because we | ||
369 | * we want SYSTEM_APERTURE to cover both VRAM and | ||
370 | * AGP so that GPU can catch out of VRAM/AGP access | ||
371 | */ | ||
372 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { | ||
373 | /* Enought place before */ | ||
374 | rdev->mc.vram_location = rdev->mc.gtt_location - | ||
375 | rdev->mc.mc_vram_size; | ||
376 | } else if (tmp > rdev->mc.mc_vram_size) { | ||
377 | /* Enought place after */ | ||
378 | rdev->mc.vram_location = rdev->mc.gtt_location + | ||
379 | rdev->mc.gtt_size; | ||
380 | } else { | ||
381 | /* Try to setup VRAM then AGP might not | ||
382 | * not work on some card | ||
383 | */ | ||
384 | rdev->mc.vram_location = 0x00000000UL; | ||
385 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
386 | } | ||
387 | } else { | ||
388 | if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { | ||
389 | rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & | ||
390 | 0xFFFF) << 24; | ||
391 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
392 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; | ||
393 | if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { | ||
394 | /* Enough place after vram */ | ||
395 | rdev->mc.gtt_location = tmp; | ||
396 | } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { | ||
397 | /* Enough place before vram */ | ||
398 | rdev->mc.gtt_location = 0; | ||
399 | } else { | ||
400 | /* Not enough place after or before shrink | ||
401 | * gart size | ||
402 | */ | ||
403 | if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { | ||
404 | rdev->mc.gtt_location = 0; | ||
405 | rdev->mc.gtt_size = rdev->mc.vram_location; | ||
406 | } else { | ||
407 | rdev->mc.gtt_location = tmp; | ||
408 | rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; | ||
409 | } | ||
410 | } | ||
411 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
412 | } else { | ||
413 | rdev->mc.vram_location = 0x00000000UL; | ||
414 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
415 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
416 | } | ||
417 | } | ||
418 | rdev->mc.vram_start = rdev->mc.vram_location; | ||
419 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size; | ||
420 | rdev->mc.gtt_start = rdev->mc.gtt_location; | ||
421 | rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size; | ||
422 | /* FIXME: we should enforce default clock in case GPU is not in | ||
423 | * default setup | ||
424 | */ | ||
425 | a.full = rfixed_const(100); | ||
426 | rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); | ||
427 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); | ||
428 | return 0; | ||
138 | } | 429 | } |
139 | 430 | ||
140 | void r600_vram_info(struct radeon_device *rdev) | 431 | /* We doesn't check that the GPU really needs a reset we simply do the |
432 | * reset, it's up to the caller to determine if the GPU needs one. We | ||
433 | * might add an helper function to check that. | ||
434 | */ | ||
435 | int r600_gpu_soft_reset(struct radeon_device *rdev) | ||
141 | { | 436 | { |
142 | r600_vram_get_type(rdev); | 437 | u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | |
143 | rdev->mc.real_vram_size = RREG32(R600_CONFIG_MEMSIZE); | 438 | S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | |
144 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | 439 | S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | |
440 | S_008010_SH_BUSY(1) | S_008010_SPI03_BUSY(1) | | ||
441 | S_008010_SMX_BUSY(1) | S_008010_SC_BUSY(1) | | ||
442 | S_008010_PA_BUSY(1) | S_008010_DB03_BUSY(1) | | ||
443 | S_008010_CR_BUSY(1) | S_008010_CB03_BUSY(1) | | ||
444 | S_008010_GUI_ACTIVE(1); | ||
445 | u32 grbm2_busy_mask = S_008014_SPI0_BUSY(1) | S_008014_SPI1_BUSY(1) | | ||
446 | S_008014_SPI2_BUSY(1) | S_008014_SPI3_BUSY(1) | | ||
447 | S_008014_TA0_BUSY(1) | S_008014_TA1_BUSY(1) | | ||
448 | S_008014_TA2_BUSY(1) | S_008014_TA3_BUSY(1) | | ||
449 | S_008014_DB0_BUSY(1) | S_008014_DB1_BUSY(1) | | ||
450 | S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | | ||
451 | S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | | ||
452 | S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); | ||
453 | u32 srbm_reset = 0; | ||
145 | 454 | ||
146 | /* Could aper size report 0 ? */ | 455 | /* Disable CP parsing/prefetching */ |
147 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 456 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); |
148 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 457 | /* Check if any of the rendering block is busy and reset it */ |
458 | if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || | ||
459 | (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { | ||
460 | WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) | | ||
461 | S_008020_SOFT_RESET_DB(1) | | ||
462 | S_008020_SOFT_RESET_CB(1) | | ||
463 | S_008020_SOFT_RESET_PA(1) | | ||
464 | S_008020_SOFT_RESET_SC(1) | | ||
465 | S_008020_SOFT_RESET_SMX(1) | | ||
466 | S_008020_SOFT_RESET_SPI(1) | | ||
467 | S_008020_SOFT_RESET_SX(1) | | ||
468 | S_008020_SOFT_RESET_SH(1) | | ||
469 | S_008020_SOFT_RESET_TC(1) | | ||
470 | S_008020_SOFT_RESET_TA(1) | | ||
471 | S_008020_SOFT_RESET_VC(1) | | ||
472 | S_008020_SOFT_RESET_VGT(1)); | ||
473 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | ||
474 | udelay(50); | ||
475 | WREG32(R_008020_GRBM_SOFT_RESET, 0); | ||
476 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | ||
477 | } | ||
478 | /* Reset CP (we always reset CP) */ | ||
479 | WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1)); | ||
480 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | ||
481 | udelay(50); | ||
482 | WREG32(R_008020_GRBM_SOFT_RESET, 0); | ||
483 | (void)RREG32(R_008020_GRBM_SOFT_RESET); | ||
484 | /* Reset others GPU block if necessary */ | ||
485 | if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
486 | srbm_reset |= S_000E60_SOFT_RESET_RLC(1); | ||
487 | if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) | ||
488 | srbm_reset |= S_000E60_SOFT_RESET_GRBM(1); | ||
489 | if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) | ||
490 | srbm_reset |= S_000E60_SOFT_RESET_IH(1); | ||
491 | if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
492 | srbm_reset |= S_000E60_SOFT_RESET_VMC(1); | ||
493 | if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
494 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
495 | if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
496 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
497 | if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
498 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
499 | if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
500 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
501 | if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
502 | srbm_reset |= S_000E60_SOFT_RESET_MC(1); | ||
503 | if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
504 | srbm_reset |= S_000E60_SOFT_RESET_RLC(1); | ||
505 | if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS))) | ||
506 | srbm_reset |= S_000E60_SOFT_RESET_SEM(1); | ||
507 | WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); | ||
508 | (void)RREG32(R_000E60_SRBM_SOFT_RESET); | ||
509 | udelay(50); | ||
510 | WREG32(R_000E60_SRBM_SOFT_RESET, 0); | ||
511 | (void)RREG32(R_000E60_SRBM_SOFT_RESET); | ||
512 | /* Wait a little for things to settle down */ | ||
513 | udelay(50); | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | int r600_gpu_reset(struct radeon_device *rdev) | ||
518 | { | ||
519 | return r600_gpu_soft_reset(rdev); | ||
520 | } | ||
521 | |||
522 | static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, | ||
523 | u32 num_backends, | ||
524 | u32 backend_disable_mask) | ||
525 | { | ||
526 | u32 backend_map = 0; | ||
527 | u32 enabled_backends_mask; | ||
528 | u32 enabled_backends_count; | ||
529 | u32 cur_pipe; | ||
530 | u32 swizzle_pipe[R6XX_MAX_PIPES]; | ||
531 | u32 cur_backend; | ||
532 | u32 i; | ||
533 | |||
534 | if (num_tile_pipes > R6XX_MAX_PIPES) | ||
535 | num_tile_pipes = R6XX_MAX_PIPES; | ||
536 | if (num_tile_pipes < 1) | ||
537 | num_tile_pipes = 1; | ||
538 | if (num_backends > R6XX_MAX_BACKENDS) | ||
539 | num_backends = R6XX_MAX_BACKENDS; | ||
540 | if (num_backends < 1) | ||
541 | num_backends = 1; | ||
542 | |||
543 | enabled_backends_mask = 0; | ||
544 | enabled_backends_count = 0; | ||
545 | for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { | ||
546 | if (((backend_disable_mask >> i) & 1) == 0) { | ||
547 | enabled_backends_mask |= (1 << i); | ||
548 | ++enabled_backends_count; | ||
549 | } | ||
550 | if (enabled_backends_count == num_backends) | ||
551 | break; | ||
552 | } | ||
553 | |||
554 | if (enabled_backends_count == 0) { | ||
555 | enabled_backends_mask = 1; | ||
556 | enabled_backends_count = 1; | ||
557 | } | ||
558 | |||
559 | if (enabled_backends_count != num_backends) | ||
560 | num_backends = enabled_backends_count; | ||
561 | |||
562 | memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); | ||
563 | switch (num_tile_pipes) { | ||
564 | case 1: | ||
565 | swizzle_pipe[0] = 0; | ||
566 | break; | ||
567 | case 2: | ||
568 | swizzle_pipe[0] = 0; | ||
569 | swizzle_pipe[1] = 1; | ||
570 | break; | ||
571 | case 3: | ||
572 | swizzle_pipe[0] = 0; | ||
573 | swizzle_pipe[1] = 1; | ||
574 | swizzle_pipe[2] = 2; | ||
575 | break; | ||
576 | case 4: | ||
577 | swizzle_pipe[0] = 0; | ||
578 | swizzle_pipe[1] = 1; | ||
579 | swizzle_pipe[2] = 2; | ||
580 | swizzle_pipe[3] = 3; | ||
581 | break; | ||
582 | case 5: | ||
583 | swizzle_pipe[0] = 0; | ||
584 | swizzle_pipe[1] = 1; | ||
585 | swizzle_pipe[2] = 2; | ||
586 | swizzle_pipe[3] = 3; | ||
587 | swizzle_pipe[4] = 4; | ||
588 | break; | ||
589 | case 6: | ||
590 | swizzle_pipe[0] = 0; | ||
591 | swizzle_pipe[1] = 2; | ||
592 | swizzle_pipe[2] = 4; | ||
593 | swizzle_pipe[3] = 5; | ||
594 | swizzle_pipe[4] = 1; | ||
595 | swizzle_pipe[5] = 3; | ||
596 | break; | ||
597 | case 7: | ||
598 | swizzle_pipe[0] = 0; | ||
599 | swizzle_pipe[1] = 2; | ||
600 | swizzle_pipe[2] = 4; | ||
601 | swizzle_pipe[3] = 6; | ||
602 | swizzle_pipe[4] = 1; | ||
603 | swizzle_pipe[5] = 3; | ||
604 | swizzle_pipe[6] = 5; | ||
605 | break; | ||
606 | case 8: | ||
607 | swizzle_pipe[0] = 0; | ||
608 | swizzle_pipe[1] = 2; | ||
609 | swizzle_pipe[2] = 4; | ||
610 | swizzle_pipe[3] = 6; | ||
611 | swizzle_pipe[4] = 1; | ||
612 | swizzle_pipe[5] = 3; | ||
613 | swizzle_pipe[6] = 5; | ||
614 | swizzle_pipe[7] = 7; | ||
615 | break; | ||
616 | } | ||
617 | |||
618 | cur_backend = 0; | ||
619 | for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { | ||
620 | while (((1 << cur_backend) & enabled_backends_mask) == 0) | ||
621 | cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; | ||
622 | |||
623 | backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); | ||
624 | |||
625 | cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; | ||
626 | } | ||
627 | |||
628 | return backend_map; | ||
629 | } | ||
630 | |||
631 | int r600_count_pipe_bits(uint32_t val) | ||
632 | { | ||
633 | int i, ret = 0; | ||
634 | |||
635 | for (i = 0; i < 32; i++) { | ||
636 | ret += val & 1; | ||
637 | val >>= 1; | ||
638 | } | ||
639 | return ret; | ||
149 | } | 640 | } |
150 | 641 | ||
642 | void r600_gpu_init(struct radeon_device *rdev) | ||
643 | { | ||
644 | u32 tiling_config; | ||
645 | u32 ramcfg; | ||
646 | u32 tmp; | ||
647 | int i, j; | ||
648 | u32 sq_config; | ||
649 | u32 sq_gpr_resource_mgmt_1 = 0; | ||
650 | u32 sq_gpr_resource_mgmt_2 = 0; | ||
651 | u32 sq_thread_resource_mgmt = 0; | ||
652 | u32 sq_stack_resource_mgmt_1 = 0; | ||
653 | u32 sq_stack_resource_mgmt_2 = 0; | ||
654 | |||
655 | /* FIXME: implement */ | ||
656 | switch (rdev->family) { | ||
657 | case CHIP_R600: | ||
658 | rdev->config.r600.max_pipes = 4; | ||
659 | rdev->config.r600.max_tile_pipes = 8; | ||
660 | rdev->config.r600.max_simds = 4; | ||
661 | rdev->config.r600.max_backends = 4; | ||
662 | rdev->config.r600.max_gprs = 256; | ||
663 | rdev->config.r600.max_threads = 192; | ||
664 | rdev->config.r600.max_stack_entries = 256; | ||
665 | rdev->config.r600.max_hw_contexts = 8; | ||
666 | rdev->config.r600.max_gs_threads = 16; | ||
667 | rdev->config.r600.sx_max_export_size = 128; | ||
668 | rdev->config.r600.sx_max_export_pos_size = 16; | ||
669 | rdev->config.r600.sx_max_export_smx_size = 128; | ||
670 | rdev->config.r600.sq_num_cf_insts = 2; | ||
671 | break; | ||
672 | case CHIP_RV630: | ||
673 | case CHIP_RV635: | ||
674 | rdev->config.r600.max_pipes = 2; | ||
675 | rdev->config.r600.max_tile_pipes = 2; | ||
676 | rdev->config.r600.max_simds = 3; | ||
677 | rdev->config.r600.max_backends = 1; | ||
678 | rdev->config.r600.max_gprs = 128; | ||
679 | rdev->config.r600.max_threads = 192; | ||
680 | rdev->config.r600.max_stack_entries = 128; | ||
681 | rdev->config.r600.max_hw_contexts = 8; | ||
682 | rdev->config.r600.max_gs_threads = 4; | ||
683 | rdev->config.r600.sx_max_export_size = 128; | ||
684 | rdev->config.r600.sx_max_export_pos_size = 16; | ||
685 | rdev->config.r600.sx_max_export_smx_size = 128; | ||
686 | rdev->config.r600.sq_num_cf_insts = 2; | ||
687 | break; | ||
688 | case CHIP_RV610: | ||
689 | case CHIP_RV620: | ||
690 | case CHIP_RS780: | ||
691 | case CHIP_RS880: | ||
692 | rdev->config.r600.max_pipes = 1; | ||
693 | rdev->config.r600.max_tile_pipes = 1; | ||
694 | rdev->config.r600.max_simds = 2; | ||
695 | rdev->config.r600.max_backends = 1; | ||
696 | rdev->config.r600.max_gprs = 128; | ||
697 | rdev->config.r600.max_threads = 192; | ||
698 | rdev->config.r600.max_stack_entries = 128; | ||
699 | rdev->config.r600.max_hw_contexts = 4; | ||
700 | rdev->config.r600.max_gs_threads = 4; | ||
701 | rdev->config.r600.sx_max_export_size = 128; | ||
702 | rdev->config.r600.sx_max_export_pos_size = 16; | ||
703 | rdev->config.r600.sx_max_export_smx_size = 128; | ||
704 | rdev->config.r600.sq_num_cf_insts = 1; | ||
705 | break; | ||
706 | case CHIP_RV670: | ||
707 | rdev->config.r600.max_pipes = 4; | ||
708 | rdev->config.r600.max_tile_pipes = 4; | ||
709 | rdev->config.r600.max_simds = 4; | ||
710 | rdev->config.r600.max_backends = 4; | ||
711 | rdev->config.r600.max_gprs = 192; | ||
712 | rdev->config.r600.max_threads = 192; | ||
713 | rdev->config.r600.max_stack_entries = 256; | ||
714 | rdev->config.r600.max_hw_contexts = 8; | ||
715 | rdev->config.r600.max_gs_threads = 16; | ||
716 | rdev->config.r600.sx_max_export_size = 128; | ||
717 | rdev->config.r600.sx_max_export_pos_size = 16; | ||
718 | rdev->config.r600.sx_max_export_smx_size = 128; | ||
719 | rdev->config.r600.sq_num_cf_insts = 2; | ||
720 | break; | ||
721 | default: | ||
722 | break; | ||
723 | } | ||
724 | |||
725 | /* Initialize HDP */ | ||
726 | for (i = 0, j = 0; i < 32; i++, j += 0x18) { | ||
727 | WREG32((0x2c14 + j), 0x00000000); | ||
728 | WREG32((0x2c18 + j), 0x00000000); | ||
729 | WREG32((0x2c1c + j), 0x00000000); | ||
730 | WREG32((0x2c20 + j), 0x00000000); | ||
731 | WREG32((0x2c24 + j), 0x00000000); | ||
732 | } | ||
733 | |||
734 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); | ||
735 | |||
736 | /* Setup tiling */ | ||
737 | tiling_config = 0; | ||
738 | ramcfg = RREG32(RAMCFG); | ||
739 | switch (rdev->config.r600.max_tile_pipes) { | ||
740 | case 1: | ||
741 | tiling_config |= PIPE_TILING(0); | ||
742 | break; | ||
743 | case 2: | ||
744 | tiling_config |= PIPE_TILING(1); | ||
745 | break; | ||
746 | case 4: | ||
747 | tiling_config |= PIPE_TILING(2); | ||
748 | break; | ||
749 | case 8: | ||
750 | tiling_config |= PIPE_TILING(3); | ||
751 | break; | ||
752 | default: | ||
753 | break; | ||
754 | } | ||
755 | tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); | ||
756 | tiling_config |= GROUP_SIZE(0); | ||
757 | tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; | ||
758 | if (tmp > 3) { | ||
759 | tiling_config |= ROW_TILING(3); | ||
760 | tiling_config |= SAMPLE_SPLIT(3); | ||
761 | } else { | ||
762 | tiling_config |= ROW_TILING(tmp); | ||
763 | tiling_config |= SAMPLE_SPLIT(tmp); | ||
764 | } | ||
765 | tiling_config |= BANK_SWAPS(1); | ||
766 | tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, | ||
767 | rdev->config.r600.max_backends, | ||
768 | (0xff << rdev->config.r600.max_backends) & 0xff); | ||
769 | tiling_config |= BACKEND_MAP(tmp); | ||
770 | WREG32(GB_TILING_CONFIG, tiling_config); | ||
771 | WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); | ||
772 | WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff); | ||
773 | |||
774 | tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); | ||
775 | WREG32(CC_RB_BACKEND_DISABLE, tmp); | ||
776 | |||
777 | /* Setup pipes */ | ||
778 | tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); | ||
779 | tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); | ||
780 | WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp); | ||
781 | WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp); | ||
782 | |||
783 | tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK); | ||
784 | WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); | ||
785 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK); | ||
786 | |||
787 | /* Setup some CP states */ | ||
788 | WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | ROQ_IB2_START(0x2b))); | ||
789 | WREG32(CP_MEQ_THRESHOLDS, (MEQ_END(0x40) | ROQ_END(0x40))); | ||
790 | |||
791 | WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | SYNC_GRADIENT | | ||
792 | SYNC_WALKER | SYNC_ALIGNER)); | ||
793 | /* Setup various GPU states */ | ||
794 | if (rdev->family == CHIP_RV670) | ||
795 | WREG32(ARB_GDEC_RD_CNTL, 0x00000021); | ||
796 | |||
797 | tmp = RREG32(SX_DEBUG_1); | ||
798 | tmp |= SMX_EVENT_RELEASE; | ||
799 | if ((rdev->family > CHIP_R600)) | ||
800 | tmp |= ENABLE_NEW_SMX_ADDRESS; | ||
801 | WREG32(SX_DEBUG_1, tmp); | ||
802 | |||
803 | if (((rdev->family) == CHIP_R600) || | ||
804 | ((rdev->family) == CHIP_RV630) || | ||
805 | ((rdev->family) == CHIP_RV610) || | ||
806 | ((rdev->family) == CHIP_RV620) || | ||
807 | ((rdev->family) == CHIP_RS780)) { | ||
808 | WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE); | ||
809 | } else { | ||
810 | WREG32(DB_DEBUG, 0); | ||
811 | } | ||
812 | WREG32(DB_WATERMARKS, (DEPTH_FREE(4) | DEPTH_CACHELINE_FREE(16) | | ||
813 | DEPTH_FLUSH(16) | DEPTH_PENDING_FREE(4))); | ||
814 | |||
815 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); | ||
816 | WREG32(VGT_NUM_INSTANCES, 0); | ||
817 | |||
818 | WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0)); | ||
819 | WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(0)); | ||
820 | |||
821 | tmp = RREG32(SQ_MS_FIFO_SIZES); | ||
822 | if (((rdev->family) == CHIP_RV610) || | ||
823 | ((rdev->family) == CHIP_RV620) || | ||
824 | ((rdev->family) == CHIP_RS780)) { | ||
825 | tmp = (CACHE_FIFO_SIZE(0xa) | | ||
826 | FETCH_FIFO_HIWATER(0xa) | | ||
827 | DONE_FIFO_HIWATER(0xe0) | | ||
828 | ALU_UPDATE_FIFO_HIWATER(0x8)); | ||
829 | } else if (((rdev->family) == CHIP_R600) || | ||
830 | ((rdev->family) == CHIP_RV630)) { | ||
831 | tmp &= ~DONE_FIFO_HIWATER(0xff); | ||
832 | tmp |= DONE_FIFO_HIWATER(0x4); | ||
833 | } | ||
834 | WREG32(SQ_MS_FIFO_SIZES, tmp); | ||
835 | |||
836 | /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT | ||
837 | * should be adjusted as needed by the 2D/3D drivers. This just sets default values | ||
838 | */ | ||
839 | sq_config = RREG32(SQ_CONFIG); | ||
840 | sq_config &= ~(PS_PRIO(3) | | ||
841 | VS_PRIO(3) | | ||
842 | GS_PRIO(3) | | ||
843 | ES_PRIO(3)); | ||
844 | sq_config |= (DX9_CONSTS | | ||
845 | VC_ENABLE | | ||
846 | PS_PRIO(0) | | ||
847 | VS_PRIO(1) | | ||
848 | GS_PRIO(2) | | ||
849 | ES_PRIO(3)); | ||
850 | |||
851 | if ((rdev->family) == CHIP_R600) { | ||
852 | sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(124) | | ||
853 | NUM_VS_GPRS(124) | | ||
854 | NUM_CLAUSE_TEMP_GPRS(4)); | ||
855 | sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(0) | | ||
856 | NUM_ES_GPRS(0)); | ||
857 | sq_thread_resource_mgmt = (NUM_PS_THREADS(136) | | ||
858 | NUM_VS_THREADS(48) | | ||
859 | NUM_GS_THREADS(4) | | ||
860 | NUM_ES_THREADS(4)); | ||
861 | sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(128) | | ||
862 | NUM_VS_STACK_ENTRIES(128)); | ||
863 | sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(0) | | ||
864 | NUM_ES_STACK_ENTRIES(0)); | ||
865 | } else if (((rdev->family) == CHIP_RV610) || | ||
866 | ((rdev->family) == CHIP_RV620) || | ||
867 | ((rdev->family) == CHIP_RS780)) { | ||
868 | /* no vertex cache */ | ||
869 | sq_config &= ~VC_ENABLE; | ||
870 | |||
871 | sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | | ||
872 | NUM_VS_GPRS(44) | | ||
873 | NUM_CLAUSE_TEMP_GPRS(2)); | ||
874 | sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) | | ||
875 | NUM_ES_GPRS(17)); | ||
876 | sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | | ||
877 | NUM_VS_THREADS(78) | | ||
878 | NUM_GS_THREADS(4) | | ||
879 | NUM_ES_THREADS(31)); | ||
880 | sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) | | ||
881 | NUM_VS_STACK_ENTRIES(40)); | ||
882 | sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) | | ||
883 | NUM_ES_STACK_ENTRIES(16)); | ||
884 | } else if (((rdev->family) == CHIP_RV630) || | ||
885 | ((rdev->family) == CHIP_RV635)) { | ||
886 | sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | | ||
887 | NUM_VS_GPRS(44) | | ||
888 | NUM_CLAUSE_TEMP_GPRS(2)); | ||
889 | sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(18) | | ||
890 | NUM_ES_GPRS(18)); | ||
891 | sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | | ||
892 | NUM_VS_THREADS(78) | | ||
893 | NUM_GS_THREADS(4) | | ||
894 | NUM_ES_THREADS(31)); | ||
895 | sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) | | ||
896 | NUM_VS_STACK_ENTRIES(40)); | ||
897 | sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) | | ||
898 | NUM_ES_STACK_ENTRIES(16)); | ||
899 | } else if ((rdev->family) == CHIP_RV670) { | ||
900 | sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | | ||
901 | NUM_VS_GPRS(44) | | ||
902 | NUM_CLAUSE_TEMP_GPRS(2)); | ||
903 | sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) | | ||
904 | NUM_ES_GPRS(17)); | ||
905 | sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | | ||
906 | NUM_VS_THREADS(78) | | ||
907 | NUM_GS_THREADS(4) | | ||
908 | NUM_ES_THREADS(31)); | ||
909 | sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(64) | | ||
910 | NUM_VS_STACK_ENTRIES(64)); | ||
911 | sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(64) | | ||
912 | NUM_ES_STACK_ENTRIES(64)); | ||
913 | } | ||
914 | |||
915 | WREG32(SQ_CONFIG, sq_config); | ||
916 | WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); | ||
917 | WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); | ||
918 | WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); | ||
919 | WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); | ||
920 | WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); | ||
921 | |||
922 | if (((rdev->family) == CHIP_RV610) || | ||
923 | ((rdev->family) == CHIP_RV620) || | ||
924 | ((rdev->family) == CHIP_RS780)) { | ||
925 | WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY)); | ||
926 | } else { | ||
927 | WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC)); | ||
928 | } | ||
929 | |||
930 | /* More default values. 2D/3D driver should adjust as needed */ | ||
931 | WREG32(PA_SC_AA_SAMPLE_LOCS_2S, (S0_X(0xc) | S0_Y(0x4) | | ||
932 | S1_X(0x4) | S1_Y(0xc))); | ||
933 | WREG32(PA_SC_AA_SAMPLE_LOCS_4S, (S0_X(0xe) | S0_Y(0xe) | | ||
934 | S1_X(0x2) | S1_Y(0x2) | | ||
935 | S2_X(0xa) | S2_Y(0x6) | | ||
936 | S3_X(0x6) | S3_Y(0xa))); | ||
937 | WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD0, (S0_X(0xe) | S0_Y(0xb) | | ||
938 | S1_X(0x4) | S1_Y(0xc) | | ||
939 | S2_X(0x1) | S2_Y(0x6) | | ||
940 | S3_X(0xa) | S3_Y(0xe))); | ||
941 | WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD1, (S4_X(0x6) | S4_Y(0x1) | | ||
942 | S5_X(0x0) | S5_Y(0x0) | | ||
943 | S6_X(0xb) | S6_Y(0x4) | | ||
944 | S7_X(0x7) | S7_Y(0x8))); | ||
945 | |||
946 | WREG32(VGT_STRMOUT_EN, 0); | ||
947 | tmp = rdev->config.r600.max_pipes * 16; | ||
948 | switch (rdev->family) { | ||
949 | case CHIP_RV610: | ||
950 | case CHIP_RS780: | ||
951 | case CHIP_RV620: | ||
952 | tmp += 32; | ||
953 | break; | ||
954 | case CHIP_RV670: | ||
955 | tmp += 128; | ||
956 | break; | ||
957 | default: | ||
958 | break; | ||
959 | } | ||
960 | if (tmp > 256) { | ||
961 | tmp = 256; | ||
962 | } | ||
963 | WREG32(VGT_ES_PER_GS, 128); | ||
964 | WREG32(VGT_GS_PER_ES, tmp); | ||
965 | WREG32(VGT_GS_PER_VS, 2); | ||
966 | WREG32(VGT_GS_VERTEX_REUSE, 16); | ||
967 | |||
968 | /* more default values. 2D/3D driver should adjust as needed */ | ||
969 | WREG32(PA_SC_LINE_STIPPLE_STATE, 0); | ||
970 | WREG32(VGT_STRMOUT_EN, 0); | ||
971 | WREG32(SX_MISC, 0); | ||
972 | WREG32(PA_SC_MODE_CNTL, 0); | ||
973 | WREG32(PA_SC_AA_CONFIG, 0); | ||
974 | WREG32(PA_SC_LINE_STIPPLE, 0); | ||
975 | WREG32(SPI_INPUT_Z, 0); | ||
976 | WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2)); | ||
977 | WREG32(CB_COLOR7_FRAG, 0); | ||
978 | |||
979 | /* Clear render buffer base addresses */ | ||
980 | WREG32(CB_COLOR0_BASE, 0); | ||
981 | WREG32(CB_COLOR1_BASE, 0); | ||
982 | WREG32(CB_COLOR2_BASE, 0); | ||
983 | WREG32(CB_COLOR3_BASE, 0); | ||
984 | WREG32(CB_COLOR4_BASE, 0); | ||
985 | WREG32(CB_COLOR5_BASE, 0); | ||
986 | WREG32(CB_COLOR6_BASE, 0); | ||
987 | WREG32(CB_COLOR7_BASE, 0); | ||
988 | WREG32(CB_COLOR7_FRAG, 0); | ||
989 | |||
990 | switch (rdev->family) { | ||
991 | case CHIP_RV610: | ||
992 | case CHIP_RS780: | ||
993 | case CHIP_RV620: | ||
994 | tmp = TC_L2_SIZE(8); | ||
995 | break; | ||
996 | case CHIP_RV630: | ||
997 | case CHIP_RV635: | ||
998 | tmp = TC_L2_SIZE(4); | ||
999 | break; | ||
1000 | case CHIP_R600: | ||
1001 | tmp = TC_L2_SIZE(0) | L2_DISABLE_LATE_HIT; | ||
1002 | break; | ||
1003 | default: | ||
1004 | tmp = TC_L2_SIZE(0); | ||
1005 | break; | ||
1006 | } | ||
1007 | WREG32(TC_CNTL, tmp); | ||
1008 | |||
1009 | tmp = RREG32(HDP_HOST_PATH_CNTL); | ||
1010 | WREG32(HDP_HOST_PATH_CNTL, tmp); | ||
1011 | |||
1012 | tmp = RREG32(ARB_POP); | ||
1013 | tmp |= ENABLE_TC128; | ||
1014 | WREG32(ARB_POP, tmp); | ||
1015 | |||
1016 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); | ||
1017 | WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | | ||
1018 | NUM_CLIP_SEQ(3))); | ||
1019 | WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); | ||
1020 | } | ||
1021 | |||
1022 | |||
151 | /* | 1023 | /* |
152 | * Indirect registers accessor | 1024 | * Indirect registers accessor |
153 | */ | 1025 | */ |
154 | uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg) | 1026 | u32 r600_pciep_rreg(struct radeon_device *rdev, u32 reg) |
1027 | { | ||
1028 | u32 r; | ||
1029 | |||
1030 | WREG32(PCIE_PORT_INDEX, ((reg) & 0xff)); | ||
1031 | (void)RREG32(PCIE_PORT_INDEX); | ||
1032 | r = RREG32(PCIE_PORT_DATA); | ||
1033 | return r; | ||
1034 | } | ||
1035 | |||
1036 | void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | ||
1037 | { | ||
1038 | WREG32(PCIE_PORT_INDEX, ((reg) & 0xff)); | ||
1039 | (void)RREG32(PCIE_PORT_INDEX); | ||
1040 | WREG32(PCIE_PORT_DATA, (v)); | ||
1041 | (void)RREG32(PCIE_PORT_DATA); | ||
1042 | } | ||
1043 | |||
1044 | |||
1045 | /* | ||
1046 | * CP & Ring | ||
1047 | */ | ||
1048 | void r600_cp_stop(struct radeon_device *rdev) | ||
1049 | { | ||
1050 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); | ||
1051 | } | ||
1052 | |||
1053 | int r600_cp_init_microcode(struct radeon_device *rdev) | ||
1054 | { | ||
1055 | struct platform_device *pdev; | ||
1056 | const char *chip_name; | ||
1057 | size_t pfp_req_size, me_req_size; | ||
1058 | char fw_name[30]; | ||
1059 | int err; | ||
1060 | |||
1061 | DRM_DEBUG("\n"); | ||
1062 | |||
1063 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); | ||
1064 | err = IS_ERR(pdev); | ||
1065 | if (err) { | ||
1066 | printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); | ||
1067 | return -EINVAL; | ||
1068 | } | ||
1069 | |||
1070 | switch (rdev->family) { | ||
1071 | case CHIP_R600: chip_name = "R600"; break; | ||
1072 | case CHIP_RV610: chip_name = "RV610"; break; | ||
1073 | case CHIP_RV630: chip_name = "RV630"; break; | ||
1074 | case CHIP_RV620: chip_name = "RV620"; break; | ||
1075 | case CHIP_RV635: chip_name = "RV635"; break; | ||
1076 | case CHIP_RV670: chip_name = "RV670"; break; | ||
1077 | case CHIP_RS780: | ||
1078 | case CHIP_RS880: chip_name = "RS780"; break; | ||
1079 | case CHIP_RV770: chip_name = "RV770"; break; | ||
1080 | case CHIP_RV730: | ||
1081 | case CHIP_RV740: chip_name = "RV730"; break; | ||
1082 | case CHIP_RV710: chip_name = "RV710"; break; | ||
1083 | default: BUG(); | ||
1084 | } | ||
1085 | |||
1086 | if (rdev->family >= CHIP_RV770) { | ||
1087 | pfp_req_size = R700_PFP_UCODE_SIZE * 4; | ||
1088 | me_req_size = R700_PM4_UCODE_SIZE * 4; | ||
1089 | } else { | ||
1090 | pfp_req_size = PFP_UCODE_SIZE * 4; | ||
1091 | me_req_size = PM4_UCODE_SIZE * 12; | ||
1092 | } | ||
1093 | |||
1094 | DRM_INFO("Loading %s CP Microcode\n", chip_name); | ||
1095 | |||
1096 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); | ||
1097 | err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); | ||
1098 | if (err) | ||
1099 | goto out; | ||
1100 | if (rdev->pfp_fw->size != pfp_req_size) { | ||
1101 | printk(KERN_ERR | ||
1102 | "r600_cp: Bogus length %zu in firmware \"%s\"\n", | ||
1103 | rdev->pfp_fw->size, fw_name); | ||
1104 | err = -EINVAL; | ||
1105 | goto out; | ||
1106 | } | ||
1107 | |||
1108 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); | ||
1109 | err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); | ||
1110 | if (err) | ||
1111 | goto out; | ||
1112 | if (rdev->me_fw->size != me_req_size) { | ||
1113 | printk(KERN_ERR | ||
1114 | "r600_cp: Bogus length %zu in firmware \"%s\"\n", | ||
1115 | rdev->me_fw->size, fw_name); | ||
1116 | err = -EINVAL; | ||
1117 | } | ||
1118 | out: | ||
1119 | platform_device_unregister(pdev); | ||
1120 | |||
1121 | if (err) { | ||
1122 | if (err != -EINVAL) | ||
1123 | printk(KERN_ERR | ||
1124 | "r600_cp: Failed to load firmware \"%s\"\n", | ||
1125 | fw_name); | ||
1126 | release_firmware(rdev->pfp_fw); | ||
1127 | rdev->pfp_fw = NULL; | ||
1128 | release_firmware(rdev->me_fw); | ||
1129 | rdev->me_fw = NULL; | ||
1130 | } | ||
1131 | return err; | ||
1132 | } | ||
1133 | |||
1134 | static int r600_cp_load_microcode(struct radeon_device *rdev) | ||
1135 | { | ||
1136 | const __be32 *fw_data; | ||
1137 | int i; | ||
1138 | |||
1139 | if (!rdev->me_fw || !rdev->pfp_fw) | ||
1140 | return -EINVAL; | ||
1141 | |||
1142 | r600_cp_stop(rdev); | ||
1143 | |||
1144 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | ||
1145 | |||
1146 | /* Reset cp */ | ||
1147 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); | ||
1148 | RREG32(GRBM_SOFT_RESET); | ||
1149 | mdelay(15); | ||
1150 | WREG32(GRBM_SOFT_RESET, 0); | ||
1151 | |||
1152 | WREG32(CP_ME_RAM_WADDR, 0); | ||
1153 | |||
1154 | fw_data = (const __be32 *)rdev->me_fw->data; | ||
1155 | WREG32(CP_ME_RAM_WADDR, 0); | ||
1156 | for (i = 0; i < PM4_UCODE_SIZE * 3; i++) | ||
1157 | WREG32(CP_ME_RAM_DATA, | ||
1158 | be32_to_cpup(fw_data++)); | ||
1159 | |||
1160 | fw_data = (const __be32 *)rdev->pfp_fw->data; | ||
1161 | WREG32(CP_PFP_UCODE_ADDR, 0); | ||
1162 | for (i = 0; i < PFP_UCODE_SIZE; i++) | ||
1163 | WREG32(CP_PFP_UCODE_DATA, | ||
1164 | be32_to_cpup(fw_data++)); | ||
1165 | |||
1166 | WREG32(CP_PFP_UCODE_ADDR, 0); | ||
1167 | WREG32(CP_ME_RAM_WADDR, 0); | ||
1168 | WREG32(CP_ME_RAM_RADDR, 0); | ||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1172 | int r600_cp_start(struct radeon_device *rdev) | ||
1173 | { | ||
1174 | int r; | ||
1175 | uint32_t cp_me; | ||
1176 | |||
1177 | r = radeon_ring_lock(rdev, 7); | ||
1178 | if (r) { | ||
1179 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
1180 | return r; | ||
1181 | } | ||
1182 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | ||
1183 | radeon_ring_write(rdev, 0x1); | ||
1184 | if (rdev->family < CHIP_RV770) { | ||
1185 | radeon_ring_write(rdev, 0x3); | ||
1186 | radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1); | ||
1187 | } else { | ||
1188 | radeon_ring_write(rdev, 0x0); | ||
1189 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); | ||
1190 | } | ||
1191 | radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | ||
1192 | radeon_ring_write(rdev, 0); | ||
1193 | radeon_ring_write(rdev, 0); | ||
1194 | radeon_ring_unlock_commit(rdev); | ||
1195 | |||
1196 | cp_me = 0xff; | ||
1197 | WREG32(R_0086D8_CP_ME_CNTL, cp_me); | ||
1198 | return 0; | ||
1199 | } | ||
1200 | |||
1201 | int r600_cp_resume(struct radeon_device *rdev) | ||
1202 | { | ||
1203 | u32 tmp; | ||
1204 | u32 rb_bufsz; | ||
1205 | int r; | ||
1206 | |||
1207 | /* Reset cp */ | ||
1208 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); | ||
1209 | RREG32(GRBM_SOFT_RESET); | ||
1210 | mdelay(15); | ||
1211 | WREG32(GRBM_SOFT_RESET, 0); | ||
1212 | |||
1213 | /* Set ring buffer size */ | ||
1214 | rb_bufsz = drm_order(rdev->cp.ring_size / 8); | ||
1215 | #ifdef __BIG_ENDIAN | ||
1216 | WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE | | ||
1217 | (drm_order(4096/8) << 8) | rb_bufsz); | ||
1218 | #else | ||
1219 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz); | ||
1220 | #endif | ||
1221 | WREG32(CP_SEM_WAIT_TIMER, 0x4); | ||
1222 | |||
1223 | /* Set the write pointer delay */ | ||
1224 | WREG32(CP_RB_WPTR_DELAY, 0); | ||
1225 | |||
1226 | /* Initialize the ring buffer's read and write pointers */ | ||
1227 | tmp = RREG32(CP_RB_CNTL); | ||
1228 | WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); | ||
1229 | WREG32(CP_RB_RPTR_WR, 0); | ||
1230 | WREG32(CP_RB_WPTR, 0); | ||
1231 | WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF); | ||
1232 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr)); | ||
1233 | mdelay(1); | ||
1234 | WREG32(CP_RB_CNTL, tmp); | ||
1235 | |||
1236 | WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8); | ||
1237 | WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); | ||
1238 | |||
1239 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | ||
1240 | rdev->cp.wptr = RREG32(CP_RB_WPTR); | ||
1241 | |||
1242 | r600_cp_start(rdev); | ||
1243 | rdev->cp.ready = true; | ||
1244 | r = radeon_ring_test(rdev); | ||
1245 | if (r) { | ||
1246 | rdev->cp.ready = false; | ||
1247 | return r; | ||
1248 | } | ||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1252 | void r600_cp_commit(struct radeon_device *rdev) | ||
1253 | { | ||
1254 | WREG32(CP_RB_WPTR, rdev->cp.wptr); | ||
1255 | (void)RREG32(CP_RB_WPTR); | ||
1256 | } | ||
1257 | |||
1258 | void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) | ||
1259 | { | ||
1260 | u32 rb_bufsz; | ||
1261 | |||
1262 | /* Align ring size */ | ||
1263 | rb_bufsz = drm_order(ring_size / 8); | ||
1264 | ring_size = (1 << (rb_bufsz + 1)) * 4; | ||
1265 | rdev->cp.ring_size = ring_size; | ||
1266 | rdev->cp.align_mask = 16 - 1; | ||
1267 | } | ||
1268 | |||
1269 | |||
1270 | /* | ||
1271 | * GPU scratch registers helpers function. | ||
1272 | */ | ||
1273 | void r600_scratch_init(struct radeon_device *rdev) | ||
1274 | { | ||
1275 | int i; | ||
1276 | |||
1277 | rdev->scratch.num_reg = 7; | ||
1278 | for (i = 0; i < rdev->scratch.num_reg; i++) { | ||
1279 | rdev->scratch.free[i] = true; | ||
1280 | rdev->scratch.reg[i] = SCRATCH_REG0 + (i * 4); | ||
1281 | } | ||
1282 | } | ||
1283 | |||
1284 | int r600_ring_test(struct radeon_device *rdev) | ||
1285 | { | ||
1286 | uint32_t scratch; | ||
1287 | uint32_t tmp = 0; | ||
1288 | unsigned i; | ||
1289 | int r; | ||
1290 | |||
1291 | r = radeon_scratch_get(rdev, &scratch); | ||
1292 | if (r) { | ||
1293 | DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); | ||
1294 | return r; | ||
1295 | } | ||
1296 | WREG32(scratch, 0xCAFEDEAD); | ||
1297 | r = radeon_ring_lock(rdev, 3); | ||
1298 | if (r) { | ||
1299 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
1300 | radeon_scratch_free(rdev, scratch); | ||
1301 | return r; | ||
1302 | } | ||
1303 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
1304 | radeon_ring_write(rdev, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | ||
1305 | radeon_ring_write(rdev, 0xDEADBEEF); | ||
1306 | radeon_ring_unlock_commit(rdev); | ||
1307 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
1308 | tmp = RREG32(scratch); | ||
1309 | if (tmp == 0xDEADBEEF) | ||
1310 | break; | ||
1311 | DRM_UDELAY(1); | ||
1312 | } | ||
1313 | if (i < rdev->usec_timeout) { | ||
1314 | DRM_INFO("ring test succeeded in %d usecs\n", i); | ||
1315 | } else { | ||
1316 | DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n", | ||
1317 | scratch, tmp); | ||
1318 | r = -EINVAL; | ||
1319 | } | ||
1320 | radeon_scratch_free(rdev, scratch); | ||
1321 | return r; | ||
1322 | } | ||
1323 | |||
1324 | /* | ||
1325 | * Writeback | ||
1326 | */ | ||
1327 | int r600_wb_init(struct radeon_device *rdev) | ||
1328 | { | ||
1329 | int r; | ||
1330 | |||
1331 | if (rdev->wb.wb_obj == NULL) { | ||
1332 | r = radeon_object_create(rdev, NULL, 4096, | ||
1333 | true, | ||
1334 | RADEON_GEM_DOMAIN_GTT, | ||
1335 | false, &rdev->wb.wb_obj); | ||
1336 | if (r) { | ||
1337 | DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r); | ||
1338 | return r; | ||
1339 | } | ||
1340 | r = radeon_object_pin(rdev->wb.wb_obj, | ||
1341 | RADEON_GEM_DOMAIN_GTT, | ||
1342 | &rdev->wb.gpu_addr); | ||
1343 | if (r) { | ||
1344 | DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r); | ||
1345 | return r; | ||
1346 | } | ||
1347 | r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | ||
1348 | if (r) { | ||
1349 | DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); | ||
1350 | return r; | ||
1351 | } | ||
1352 | } | ||
1353 | WREG32(SCRATCH_ADDR, (rdev->wb.gpu_addr >> 8) & 0xFFFFFFFF); | ||
1354 | WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + 1024) & 0xFFFFFFFC); | ||
1355 | WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 1024) & 0xFF); | ||
1356 | WREG32(SCRATCH_UMSK, 0xff); | ||
1357 | return 0; | ||
1358 | } | ||
1359 | |||
1360 | void r600_wb_fini(struct radeon_device *rdev) | ||
1361 | { | ||
1362 | if (rdev->wb.wb_obj) { | ||
1363 | radeon_object_kunmap(rdev->wb.wb_obj); | ||
1364 | radeon_object_unpin(rdev->wb.wb_obj); | ||
1365 | radeon_object_unref(&rdev->wb.wb_obj); | ||
1366 | rdev->wb.wb = NULL; | ||
1367 | rdev->wb.wb_obj = NULL; | ||
1368 | } | ||
1369 | } | ||
1370 | |||
1371 | |||
1372 | /* | ||
1373 | * CS | ||
1374 | */ | ||
1375 | void r600_fence_ring_emit(struct radeon_device *rdev, | ||
1376 | struct radeon_fence *fence) | ||
1377 | { | ||
1378 | /* Emit fence sequence & fire IRQ */ | ||
1379 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
1380 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | ||
1381 | radeon_ring_write(rdev, fence->seq); | ||
1382 | } | ||
1383 | |||
1384 | int r600_copy_dma(struct radeon_device *rdev, | ||
1385 | uint64_t src_offset, | ||
1386 | uint64_t dst_offset, | ||
1387 | unsigned num_pages, | ||
1388 | struct radeon_fence *fence) | ||
1389 | { | ||
1390 | /* FIXME: implement */ | ||
1391 | return 0; | ||
1392 | } | ||
1393 | |||
1394 | int r600_copy_blit(struct radeon_device *rdev, | ||
1395 | uint64_t src_offset, uint64_t dst_offset, | ||
1396 | unsigned num_pages, struct radeon_fence *fence) | ||
1397 | { | ||
1398 | r600_blit_prepare_copy(rdev, num_pages * 4096); | ||
1399 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096); | ||
1400 | r600_blit_done_copy(rdev, fence); | ||
1401 | return 0; | ||
1402 | } | ||
1403 | |||
1404 | int r600_irq_process(struct radeon_device *rdev) | ||
1405 | { | ||
1406 | /* FIXME: implement */ | ||
1407 | return 0; | ||
1408 | } | ||
1409 | |||
1410 | int r600_irq_set(struct radeon_device *rdev) | ||
1411 | { | ||
1412 | /* FIXME: implement */ | ||
1413 | return 0; | ||
1414 | } | ||
1415 | |||
1416 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, | ||
1417 | uint32_t tiling_flags, uint32_t pitch, | ||
1418 | uint32_t offset, uint32_t obj_size) | ||
1419 | { | ||
1420 | /* FIXME: implement */ | ||
1421 | return 0; | ||
1422 | } | ||
1423 | |||
1424 | void r600_clear_surface_reg(struct radeon_device *rdev, int reg) | ||
1425 | { | ||
1426 | /* FIXME: implement */ | ||
1427 | } | ||
1428 | |||
1429 | |||
1430 | bool r600_card_posted(struct radeon_device *rdev) | ||
1431 | { | ||
1432 | uint32_t reg; | ||
1433 | |||
1434 | /* first check CRTCs */ | ||
1435 | reg = RREG32(D1CRTC_CONTROL) | | ||
1436 | RREG32(D2CRTC_CONTROL); | ||
1437 | if (reg & CRTC_EN) | ||
1438 | return true; | ||
1439 | |||
1440 | /* then check MEM_SIZE, in case the crtcs are off */ | ||
1441 | if (RREG32(CONFIG_MEMSIZE)) | ||
1442 | return true; | ||
1443 | |||
1444 | return false; | ||
1445 | } | ||
1446 | |||
1447 | int r600_resume(struct radeon_device *rdev) | ||
1448 | { | ||
1449 | int r; | ||
1450 | |||
1451 | r600_gpu_reset(rdev); | ||
1452 | r600_mc_resume(rdev); | ||
1453 | r = r600_pcie_gart_enable(rdev); | ||
1454 | if (r) | ||
1455 | return r; | ||
1456 | r600_gpu_init(rdev); | ||
1457 | r = radeon_ring_init(rdev, rdev->cp.ring_size); | ||
1458 | if (r) | ||
1459 | return r; | ||
1460 | r = r600_cp_load_microcode(rdev); | ||
1461 | if (r) | ||
1462 | return r; | ||
1463 | r = r600_cp_resume(rdev); | ||
1464 | if (r) | ||
1465 | return r; | ||
1466 | r = r600_wb_init(rdev); | ||
1467 | if (r) | ||
1468 | return r; | ||
1469 | return 0; | ||
1470 | } | ||
1471 | |||
1472 | int r600_suspend(struct radeon_device *rdev) | ||
1473 | { | ||
1474 | /* FIXME: we should wait for ring to be empty */ | ||
1475 | r600_cp_stop(rdev); | ||
1476 | return 0; | ||
1477 | } | ||
1478 | |||
1479 | /* Plan is to move initialization in that function and use | ||
1480 | * helper function so that radeon_device_init pretty much | ||
1481 | * do nothing more than calling asic specific function. This | ||
1482 | * should also allow to remove a bunch of callback function | ||
1483 | * like vram_info. | ||
1484 | */ | ||
1485 | int r600_init(struct radeon_device *rdev) | ||
155 | { | 1486 | { |
156 | uint32_t r; | 1487 | int r; |
157 | 1488 | ||
158 | WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff)); | 1489 | rdev->new_init_path = true; |
159 | (void)RREG32(R600_PCIE_PORT_INDEX); | 1490 | r = radeon_dummy_page_init(rdev); |
160 | r = RREG32(R600_PCIE_PORT_DATA); | 1491 | if (r) |
1492 | return r; | ||
1493 | if (r600_debugfs_mc_info_init(rdev)) { | ||
1494 | DRM_ERROR("Failed to register debugfs file for mc !\n"); | ||
1495 | } | ||
1496 | /* This don't do much */ | ||
1497 | r = radeon_gem_init(rdev); | ||
1498 | if (r) | ||
1499 | return r; | ||
1500 | /* Read BIOS */ | ||
1501 | if (!radeon_get_bios(rdev)) { | ||
1502 | if (ASIC_IS_AVIVO(rdev)) | ||
1503 | return -EINVAL; | ||
1504 | } | ||
1505 | /* Must be an ATOMBIOS */ | ||
1506 | if (!rdev->is_atom_bios) | ||
1507 | return -EINVAL; | ||
1508 | r = radeon_atombios_init(rdev); | ||
1509 | if (r) | ||
1510 | return r; | ||
1511 | /* Post card if necessary */ | ||
1512 | if (!r600_card_posted(rdev) && rdev->bios) { | ||
1513 | DRM_INFO("GPU not posted. posting now...\n"); | ||
1514 | atom_asic_init(rdev->mode_info.atom_context); | ||
1515 | } | ||
1516 | /* Initialize scratch registers */ | ||
1517 | r600_scratch_init(rdev); | ||
1518 | /* Initialize surface registers */ | ||
1519 | radeon_surface_init(rdev); | ||
1520 | r = radeon_clocks_init(rdev); | ||
1521 | if (r) | ||
1522 | return r; | ||
1523 | /* Fence driver */ | ||
1524 | r = radeon_fence_driver_init(rdev); | ||
1525 | if (r) | ||
1526 | return r; | ||
1527 | r = r600_mc_init(rdev); | ||
1528 | if (r) { | ||
1529 | if (rdev->flags & RADEON_IS_AGP) { | ||
1530 | /* Retry with disabling AGP */ | ||
1531 | r600_fini(rdev); | ||
1532 | rdev->flags &= ~RADEON_IS_AGP; | ||
1533 | return r600_init(rdev); | ||
1534 | } | ||
1535 | return r; | ||
1536 | } | ||
1537 | /* Memory manager */ | ||
1538 | r = radeon_object_init(rdev); | ||
1539 | if (r) | ||
1540 | return r; | ||
1541 | rdev->cp.ring_obj = NULL; | ||
1542 | r600_ring_init(rdev, 1024 * 1024); | ||
1543 | |||
1544 | if (!rdev->me_fw || !rdev->pfp_fw) { | ||
1545 | r = r600_cp_init_microcode(rdev); | ||
1546 | if (r) { | ||
1547 | DRM_ERROR("Failed to load firmware!\n"); | ||
1548 | return r; | ||
1549 | } | ||
1550 | } | ||
1551 | |||
1552 | r = r600_resume(rdev); | ||
1553 | if (r) { | ||
1554 | if (rdev->flags & RADEON_IS_AGP) { | ||
1555 | /* Retry with disabling AGP */ | ||
1556 | r600_fini(rdev); | ||
1557 | rdev->flags &= ~RADEON_IS_AGP; | ||
1558 | return r600_init(rdev); | ||
1559 | } | ||
1560 | return r; | ||
1561 | } | ||
1562 | r = radeon_ib_pool_init(rdev); | ||
1563 | if (r) { | ||
1564 | DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); | ||
1565 | return r; | ||
1566 | } | ||
1567 | r = r600_blit_init(rdev); | ||
1568 | if (r) { | ||
1569 | DRM_ERROR("radeon: failled blitter (%d).\n", r); | ||
1570 | return r; | ||
1571 | } | ||
1572 | r = radeon_ib_test(rdev); | ||
1573 | if (r) { | ||
1574 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | ||
1575 | return r; | ||
1576 | } | ||
1577 | return 0; | ||
1578 | } | ||
1579 | |||
1580 | void r600_fini(struct radeon_device *rdev) | ||
1581 | { | ||
1582 | /* Suspend operations */ | ||
1583 | r600_suspend(rdev); | ||
1584 | |||
1585 | r600_blit_fini(rdev); | ||
1586 | radeon_ring_fini(rdev); | ||
1587 | r600_pcie_gart_disable(rdev); | ||
1588 | radeon_gart_table_vram_free(rdev); | ||
1589 | radeon_gart_fini(rdev); | ||
1590 | radeon_gem_fini(rdev); | ||
1591 | radeon_fence_driver_fini(rdev); | ||
1592 | radeon_clocks_fini(rdev); | ||
1593 | #if __OS_HAS_AGP | ||
1594 | if (rdev->flags & RADEON_IS_AGP) | ||
1595 | radeon_agp_fini(rdev); | ||
1596 | #endif | ||
1597 | radeon_object_fini(rdev); | ||
1598 | if (rdev->is_atom_bios) | ||
1599 | radeon_atombios_fini(rdev); | ||
1600 | else | ||
1601 | radeon_combios_fini(rdev); | ||
1602 | kfree(rdev->bios); | ||
1603 | rdev->bios = NULL; | ||
1604 | radeon_dummy_page_fini(rdev); | ||
1605 | } | ||
1606 | |||
1607 | |||
1608 | /* | ||
1609 | * CS stuff | ||
1610 | */ | ||
1611 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) | ||
1612 | { | ||
1613 | /* FIXME: implement */ | ||
1614 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | ||
1615 | radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); | ||
1616 | radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); | ||
1617 | radeon_ring_write(rdev, ib->length_dw); | ||
1618 | } | ||
1619 | |||
1620 | int r600_ib_test(struct radeon_device *rdev) | ||
1621 | { | ||
1622 | struct radeon_ib *ib; | ||
1623 | uint32_t scratch; | ||
1624 | uint32_t tmp = 0; | ||
1625 | unsigned i; | ||
1626 | int r; | ||
1627 | |||
1628 | r = radeon_scratch_get(rdev, &scratch); | ||
1629 | if (r) { | ||
1630 | DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); | ||
1631 | return r; | ||
1632 | } | ||
1633 | WREG32(scratch, 0xCAFEDEAD); | ||
1634 | r = radeon_ib_get(rdev, &ib); | ||
1635 | if (r) { | ||
1636 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); | ||
1637 | return r; | ||
1638 | } | ||
1639 | ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); | ||
1640 | ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | ||
1641 | ib->ptr[2] = 0xDEADBEEF; | ||
1642 | ib->ptr[3] = PACKET2(0); | ||
1643 | ib->ptr[4] = PACKET2(0); | ||
1644 | ib->ptr[5] = PACKET2(0); | ||
1645 | ib->ptr[6] = PACKET2(0); | ||
1646 | ib->ptr[7] = PACKET2(0); | ||
1647 | ib->ptr[8] = PACKET2(0); | ||
1648 | ib->ptr[9] = PACKET2(0); | ||
1649 | ib->ptr[10] = PACKET2(0); | ||
1650 | ib->ptr[11] = PACKET2(0); | ||
1651 | ib->ptr[12] = PACKET2(0); | ||
1652 | ib->ptr[13] = PACKET2(0); | ||
1653 | ib->ptr[14] = PACKET2(0); | ||
1654 | ib->ptr[15] = PACKET2(0); | ||
1655 | ib->length_dw = 16; | ||
1656 | r = radeon_ib_schedule(rdev, ib); | ||
1657 | if (r) { | ||
1658 | radeon_scratch_free(rdev, scratch); | ||
1659 | radeon_ib_free(rdev, &ib); | ||
1660 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); | ||
1661 | return r; | ||
1662 | } | ||
1663 | r = radeon_fence_wait(ib->fence, false); | ||
1664 | if (r) { | ||
1665 | DRM_ERROR("radeon: fence wait failed (%d).\n", r); | ||
1666 | return r; | ||
1667 | } | ||
1668 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
1669 | tmp = RREG32(scratch); | ||
1670 | if (tmp == 0xDEADBEEF) | ||
1671 | break; | ||
1672 | DRM_UDELAY(1); | ||
1673 | } | ||
1674 | if (i < rdev->usec_timeout) { | ||
1675 | DRM_INFO("ib test succeeded in %u usecs\n", i); | ||
1676 | } else { | ||
1677 | DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", | ||
1678 | scratch, tmp); | ||
1679 | r = -EINVAL; | ||
1680 | } | ||
1681 | radeon_scratch_free(rdev, scratch); | ||
1682 | radeon_ib_free(rdev, &ib); | ||
161 | return r; | 1683 | return r; |
162 | } | 1684 | } |
163 | 1685 | ||
164 | void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | 1686 | |
1687 | |||
1688 | |||
1689 | /* | ||
1690 | * Debugfs info | ||
1691 | */ | ||
1692 | #if defined(CONFIG_DEBUG_FS) | ||
1693 | |||
1694 | static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) | ||
165 | { | 1695 | { |
166 | WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff)); | 1696 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
167 | (void)RREG32(R600_PCIE_PORT_INDEX); | 1697 | struct drm_device *dev = node->minor->dev; |
168 | WREG32(R600_PCIE_PORT_DATA, (v)); | 1698 | struct radeon_device *rdev = dev->dev_private; |
169 | (void)RREG32(R600_PCIE_PORT_DATA); | 1699 | uint32_t rdp, wdp; |
1700 | unsigned count, i, j; | ||
1701 | |||
1702 | radeon_ring_free_size(rdev); | ||
1703 | rdp = RREG32(CP_RB_RPTR); | ||
1704 | wdp = RREG32(CP_RB_WPTR); | ||
1705 | count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask; | ||
1706 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); | ||
1707 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); | ||
1708 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); | ||
1709 | seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); | ||
1710 | seq_printf(m, "%u dwords in ring\n", count); | ||
1711 | for (j = 0; j <= count; j++) { | ||
1712 | i = (rdp + j) & rdev->cp.ptr_mask; | ||
1713 | seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); | ||
1714 | } | ||
1715 | return 0; | ||
1716 | } | ||
1717 | |||
1718 | static int r600_debugfs_mc_info(struct seq_file *m, void *data) | ||
1719 | { | ||
1720 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1721 | struct drm_device *dev = node->minor->dev; | ||
1722 | struct radeon_device *rdev = dev->dev_private; | ||
1723 | |||
1724 | DREG32_SYS(m, rdev, R_000E50_SRBM_STATUS); | ||
1725 | DREG32_SYS(m, rdev, VM_L2_STATUS); | ||
1726 | return 0; | ||
1727 | } | ||
1728 | |||
1729 | static struct drm_info_list r600_mc_info_list[] = { | ||
1730 | {"r600_mc_info", r600_debugfs_mc_info, 0, NULL}, | ||
1731 | {"r600_ring_info", r600_debugfs_cp_ring_info, 0, NULL}, | ||
1732 | }; | ||
1733 | #endif | ||
1734 | |||
1735 | int r600_debugfs_mc_info_init(struct radeon_device *rdev) | ||
1736 | { | ||
1737 | #if defined(CONFIG_DEBUG_FS) | ||
1738 | return radeon_debugfs_add_files(rdev, r600_mc_info_list, ARRAY_SIZE(r600_mc_info_list)); | ||
1739 | #else | ||
1740 | return 0; | ||
1741 | #endif | ||
170 | } | 1742 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c new file mode 100644 index 000000000000..c51402e92493 --- /dev/null +++ b/drivers/gpu/drm/radeon/r600_blit.c | |||
@@ -0,0 +1,855 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
21 | * DEALINGS IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Alex Deucher <alexander.deucher@amd.com> | ||
25 | */ | ||
26 | #include "drmP.h" | ||
27 | #include "drm.h" | ||
28 | #include "radeon_drm.h" | ||
29 | #include "radeon_drv.h" | ||
30 | |||
31 | #include "r600_blit_shaders.h" | ||
32 | |||
33 | #define DI_PT_RECTLIST 0x11 | ||
34 | #define DI_INDEX_SIZE_16_BIT 0x0 | ||
35 | #define DI_SRC_SEL_AUTO_INDEX 0x2 | ||
36 | |||
37 | #define FMT_8 0x1 | ||
38 | #define FMT_5_6_5 0x8 | ||
39 | #define FMT_8_8_8_8 0x1a | ||
40 | #define COLOR_8 0x1 | ||
41 | #define COLOR_5_6_5 0x8 | ||
42 | #define COLOR_8_8_8_8 0x1a | ||
43 | |||
44 | static inline void | ||
45 | set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr) | ||
46 | { | ||
47 | u32 cb_color_info; | ||
48 | int pitch, slice; | ||
49 | RING_LOCALS; | ||
50 | DRM_DEBUG("\n"); | ||
51 | |||
52 | h = (h + 7) & ~7; | ||
53 | if (h < 8) | ||
54 | h = 8; | ||
55 | |||
56 | cb_color_info = ((format << 2) | (1 << 27)); | ||
57 | pitch = (w / 8) - 1; | ||
58 | slice = ((w * h) / 64) - 1; | ||
59 | |||
60 | if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) && | ||
61 | ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) { | ||
62 | BEGIN_RING(21 + 2); | ||
63 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
64 | OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
65 | OUT_RING(gpu_addr >> 8); | ||
66 | OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0)); | ||
67 | OUT_RING(2 << 0); | ||
68 | } else { | ||
69 | BEGIN_RING(21); | ||
70 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
71 | OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
72 | OUT_RING(gpu_addr >> 8); | ||
73 | } | ||
74 | |||
75 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
76 | OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
77 | OUT_RING((pitch << 0) | (slice << 10)); | ||
78 | |||
79 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
80 | OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
81 | OUT_RING(0); | ||
82 | |||
83 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
84 | OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
85 | OUT_RING(cb_color_info); | ||
86 | |||
87 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
88 | OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
89 | OUT_RING(0); | ||
90 | |||
91 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
92 | OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
93 | OUT_RING(0); | ||
94 | |||
95 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
96 | OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
97 | OUT_RING(0); | ||
98 | |||
99 | ADVANCE_RING(); | ||
100 | } | ||
101 | |||
102 | static inline void | ||
103 | cp_set_surface_sync(drm_radeon_private_t *dev_priv, | ||
104 | u32 sync_type, u32 size, u64 mc_addr) | ||
105 | { | ||
106 | u32 cp_coher_size; | ||
107 | RING_LOCALS; | ||
108 | DRM_DEBUG("\n"); | ||
109 | |||
110 | if (size == 0xffffffff) | ||
111 | cp_coher_size = 0xffffffff; | ||
112 | else | ||
113 | cp_coher_size = ((size + 255) >> 8); | ||
114 | |||
115 | BEGIN_RING(5); | ||
116 | OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3)); | ||
117 | OUT_RING(sync_type); | ||
118 | OUT_RING(cp_coher_size); | ||
119 | OUT_RING((mc_addr >> 8)); | ||
120 | OUT_RING(10); /* poll interval */ | ||
121 | ADVANCE_RING(); | ||
122 | } | ||
123 | |||
124 | static inline void | ||
125 | set_shaders(struct drm_device *dev) | ||
126 | { | ||
127 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
128 | u64 gpu_addr; | ||
129 | int shader_size, i; | ||
130 | u32 *vs, *ps; | ||
131 | uint32_t sq_pgm_resources; | ||
132 | RING_LOCALS; | ||
133 | DRM_DEBUG("\n"); | ||
134 | |||
135 | /* load shaders */ | ||
136 | vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset); | ||
137 | ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); | ||
138 | |||
139 | shader_size = r6xx_vs_size; | ||
140 | for (i = 0; i < shader_size; i++) | ||
141 | vs[i] = r6xx_vs[i]; | ||
142 | shader_size = r6xx_ps_size; | ||
143 | for (i = 0; i < shader_size; i++) | ||
144 | ps[i] = r6xx_ps[i]; | ||
145 | |||
146 | dev_priv->blit_vb->used = 512; | ||
147 | |||
148 | gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset; | ||
149 | |||
150 | /* setup shader regs */ | ||
151 | sq_pgm_resources = (1 << 0); | ||
152 | |||
153 | BEGIN_RING(9 + 12); | ||
154 | /* VS */ | ||
155 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
156 | OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
157 | OUT_RING(gpu_addr >> 8); | ||
158 | |||
159 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
160 | OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
161 | OUT_RING(sq_pgm_resources); | ||
162 | |||
163 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
164 | OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
165 | OUT_RING(0); | ||
166 | |||
167 | /* PS */ | ||
168 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
169 | OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
170 | OUT_RING((gpu_addr + 256) >> 8); | ||
171 | |||
172 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
173 | OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
174 | OUT_RING(sq_pgm_resources | (1 << 28)); | ||
175 | |||
176 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
177 | OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
178 | OUT_RING(2); | ||
179 | |||
180 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); | ||
181 | OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
182 | OUT_RING(0); | ||
183 | ADVANCE_RING(); | ||
184 | |||
185 | cp_set_surface_sync(dev_priv, | ||
186 | R600_SH_ACTION_ENA, 512, gpu_addr); | ||
187 | } | ||
188 | |||
189 | static inline void | ||
190 | set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) | ||
191 | { | ||
192 | uint32_t sq_vtx_constant_word2; | ||
193 | RING_LOCALS; | ||
194 | DRM_DEBUG("\n"); | ||
195 | |||
196 | sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); | ||
197 | |||
198 | BEGIN_RING(9); | ||
199 | OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); | ||
200 | OUT_RING(0x460); | ||
201 | OUT_RING(gpu_addr & 0xffffffff); | ||
202 | OUT_RING(48 - 1); | ||
203 | OUT_RING(sq_vtx_constant_word2); | ||
204 | OUT_RING(1 << 0); | ||
205 | OUT_RING(0); | ||
206 | OUT_RING(0); | ||
207 | OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30); | ||
208 | ADVANCE_RING(); | ||
209 | |||
210 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || | ||
211 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || | ||
212 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || | ||
213 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) || | ||
214 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) | ||
215 | cp_set_surface_sync(dev_priv, | ||
216 | R600_TC_ACTION_ENA, 48, gpu_addr); | ||
217 | else | ||
218 | cp_set_surface_sync(dev_priv, | ||
219 | R600_VC_ACTION_ENA, 48, gpu_addr); | ||
220 | } | ||
221 | |||
222 | static inline void | ||
223 | set_tex_resource(drm_radeon_private_t *dev_priv, | ||
224 | int format, int w, int h, int pitch, u64 gpu_addr) | ||
225 | { | ||
226 | uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; | ||
227 | RING_LOCALS; | ||
228 | DRM_DEBUG("\n"); | ||
229 | |||
230 | if (h < 1) | ||
231 | h = 1; | ||
232 | |||
233 | sq_tex_resource_word0 = (1 << 0); | ||
234 | sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | | ||
235 | ((w - 1) << 19)); | ||
236 | |||
237 | sq_tex_resource_word1 = (format << 26); | ||
238 | sq_tex_resource_word1 |= ((h - 1) << 0); | ||
239 | |||
240 | sq_tex_resource_word4 = ((1 << 14) | | ||
241 | (0 << 16) | | ||
242 | (1 << 19) | | ||
243 | (2 << 22) | | ||
244 | (3 << 25)); | ||
245 | |||
246 | BEGIN_RING(9); | ||
247 | OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); | ||
248 | OUT_RING(0); | ||
249 | OUT_RING(sq_tex_resource_word0); | ||
250 | OUT_RING(sq_tex_resource_word1); | ||
251 | OUT_RING(gpu_addr >> 8); | ||
252 | OUT_RING(gpu_addr >> 8); | ||
253 | OUT_RING(sq_tex_resource_word4); | ||
254 | OUT_RING(0); | ||
255 | OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30); | ||
256 | ADVANCE_RING(); | ||
257 | |||
258 | } | ||
259 | |||
260 | static inline void | ||
261 | set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2) | ||
262 | { | ||
263 | RING_LOCALS; | ||
264 | DRM_DEBUG("\n"); | ||
265 | |||
266 | BEGIN_RING(12); | ||
267 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); | ||
268 | OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
269 | OUT_RING((x1 << 0) | (y1 << 16)); | ||
270 | OUT_RING((x2 << 0) | (y2 << 16)); | ||
271 | |||
272 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); | ||
273 | OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
274 | OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); | ||
275 | OUT_RING((x2 << 0) | (y2 << 16)); | ||
276 | |||
277 | OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); | ||
278 | OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); | ||
279 | OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); | ||
280 | OUT_RING((x2 << 0) | (y2 << 16)); | ||
281 | ADVANCE_RING(); | ||
282 | } | ||
283 | |||
284 | static inline void | ||
285 | draw_auto(drm_radeon_private_t *dev_priv) | ||
286 | { | ||
287 | RING_LOCALS; | ||
288 | DRM_DEBUG("\n"); | ||
289 | |||
290 | BEGIN_RING(10); | ||
291 | OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); | ||
292 | OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2); | ||
293 | OUT_RING(DI_PT_RECTLIST); | ||
294 | |||
295 | OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); | ||
296 | OUT_RING(DI_INDEX_SIZE_16_BIT); | ||
297 | |||
298 | OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); | ||
299 | OUT_RING(1); | ||
300 | |||
301 | OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); | ||
302 | OUT_RING(3); | ||
303 | OUT_RING(DI_SRC_SEL_AUTO_INDEX); | ||
304 | |||
305 | ADVANCE_RING(); | ||
306 | COMMIT_RING(); | ||
307 | } | ||
308 | |||
309 | static inline void | ||
310 | set_default_state(drm_radeon_private_t *dev_priv) | ||
311 | { | ||
312 | int default_state_dw, i; | ||
313 | u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; | ||
314 | u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; | ||
315 | int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; | ||
316 | int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; | ||
317 | int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; | ||
318 | RING_LOCALS; | ||
319 | |||
320 | switch ((dev_priv->flags & RADEON_FAMILY_MASK)) { | ||
321 | case CHIP_R600: | ||
322 | num_ps_gprs = 192; | ||
323 | num_vs_gprs = 56; | ||
324 | num_temp_gprs = 4; | ||
325 | num_gs_gprs = 0; | ||
326 | num_es_gprs = 0; | ||
327 | num_ps_threads = 136; | ||
328 | num_vs_threads = 48; | ||
329 | num_gs_threads = 4; | ||
330 | num_es_threads = 4; | ||
331 | num_ps_stack_entries = 128; | ||
332 | num_vs_stack_entries = 128; | ||
333 | num_gs_stack_entries = 0; | ||
334 | num_es_stack_entries = 0; | ||
335 | break; | ||
336 | case CHIP_RV630: | ||
337 | case CHIP_RV635: | ||
338 | num_ps_gprs = 84; | ||
339 | num_vs_gprs = 36; | ||
340 | num_temp_gprs = 4; | ||
341 | num_gs_gprs = 0; | ||
342 | num_es_gprs = 0; | ||
343 | num_ps_threads = 144; | ||
344 | num_vs_threads = 40; | ||
345 | num_gs_threads = 4; | ||
346 | num_es_threads = 4; | ||
347 | num_ps_stack_entries = 40; | ||
348 | num_vs_stack_entries = 40; | ||
349 | num_gs_stack_entries = 32; | ||
350 | num_es_stack_entries = 16; | ||
351 | break; | ||
352 | case CHIP_RV610: | ||
353 | case CHIP_RV620: | ||
354 | case CHIP_RS780: | ||
355 | case CHIP_RS880: | ||
356 | default: | ||
357 | num_ps_gprs = 84; | ||
358 | num_vs_gprs = 36; | ||
359 | num_temp_gprs = 4; | ||
360 | num_gs_gprs = 0; | ||
361 | num_es_gprs = 0; | ||
362 | num_ps_threads = 136; | ||
363 | num_vs_threads = 48; | ||
364 | num_gs_threads = 4; | ||
365 | num_es_threads = 4; | ||
366 | num_ps_stack_entries = 40; | ||
367 | num_vs_stack_entries = 40; | ||
368 | num_gs_stack_entries = 32; | ||
369 | num_es_stack_entries = 16; | ||
370 | break; | ||
371 | case CHIP_RV670: | ||
372 | num_ps_gprs = 144; | ||
373 | num_vs_gprs = 40; | ||
374 | num_temp_gprs = 4; | ||
375 | num_gs_gprs = 0; | ||
376 | num_es_gprs = 0; | ||
377 | num_ps_threads = 136; | ||
378 | num_vs_threads = 48; | ||
379 | num_gs_threads = 4; | ||
380 | num_es_threads = 4; | ||
381 | num_ps_stack_entries = 40; | ||
382 | num_vs_stack_entries = 40; | ||
383 | num_gs_stack_entries = 32; | ||
384 | num_es_stack_entries = 16; | ||
385 | break; | ||
386 | case CHIP_RV770: | ||
387 | num_ps_gprs = 192; | ||
388 | num_vs_gprs = 56; | ||
389 | num_temp_gprs = 4; | ||
390 | num_gs_gprs = 0; | ||
391 | num_es_gprs = 0; | ||
392 | num_ps_threads = 188; | ||
393 | num_vs_threads = 60; | ||
394 | num_gs_threads = 0; | ||
395 | num_es_threads = 0; | ||
396 | num_ps_stack_entries = 256; | ||
397 | num_vs_stack_entries = 256; | ||
398 | num_gs_stack_entries = 0; | ||
399 | num_es_stack_entries = 0; | ||
400 | break; | ||
401 | case CHIP_RV730: | ||
402 | case CHIP_RV740: | ||
403 | num_ps_gprs = 84; | ||
404 | num_vs_gprs = 36; | ||
405 | num_temp_gprs = 4; | ||
406 | num_gs_gprs = 0; | ||
407 | num_es_gprs = 0; | ||
408 | num_ps_threads = 188; | ||
409 | num_vs_threads = 60; | ||
410 | num_gs_threads = 0; | ||
411 | num_es_threads = 0; | ||
412 | num_ps_stack_entries = 128; | ||
413 | num_vs_stack_entries = 128; | ||
414 | num_gs_stack_entries = 0; | ||
415 | num_es_stack_entries = 0; | ||
416 | break; | ||
417 | case CHIP_RV710: | ||
418 | num_ps_gprs = 192; | ||
419 | num_vs_gprs = 56; | ||
420 | num_temp_gprs = 4; | ||
421 | num_gs_gprs = 0; | ||
422 | num_es_gprs = 0; | ||
423 | num_ps_threads = 144; | ||
424 | num_vs_threads = 48; | ||
425 | num_gs_threads = 0; | ||
426 | num_es_threads = 0; | ||
427 | num_ps_stack_entries = 128; | ||
428 | num_vs_stack_entries = 128; | ||
429 | num_gs_stack_entries = 0; | ||
430 | num_es_stack_entries = 0; | ||
431 | break; | ||
432 | } | ||
433 | |||
434 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || | ||
435 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || | ||
436 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || | ||
437 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) || | ||
438 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) | ||
439 | sq_config = 0; | ||
440 | else | ||
441 | sq_config = R600_VC_ENABLE; | ||
442 | |||
443 | sq_config |= (R600_DX9_CONSTS | | ||
444 | R600_ALU_INST_PREFER_VECTOR | | ||
445 | R600_PS_PRIO(0) | | ||
446 | R600_VS_PRIO(1) | | ||
447 | R600_GS_PRIO(2) | | ||
448 | R600_ES_PRIO(3)); | ||
449 | |||
450 | sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) | | ||
451 | R600_NUM_VS_GPRS(num_vs_gprs) | | ||
452 | R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); | ||
453 | sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) | | ||
454 | R600_NUM_ES_GPRS(num_es_gprs)); | ||
455 | sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) | | ||
456 | R600_NUM_VS_THREADS(num_vs_threads) | | ||
457 | R600_NUM_GS_THREADS(num_gs_threads) | | ||
458 | R600_NUM_ES_THREADS(num_es_threads)); | ||
459 | sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | | ||
460 | R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); | ||
461 | sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | | ||
462 | R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries)); | ||
463 | |||
464 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { | ||
465 | default_state_dw = r7xx_default_size * 4; | ||
466 | BEGIN_RING(default_state_dw + 10); | ||
467 | for (i = 0; i < default_state_dw; i++) | ||
468 | OUT_RING(r7xx_default_state[i]); | ||
469 | } else { | ||
470 | default_state_dw = r6xx_default_size * 4; | ||
471 | BEGIN_RING(default_state_dw + 10); | ||
472 | for (i = 0; i < default_state_dw; i++) | ||
473 | OUT_RING(r6xx_default_state[i]); | ||
474 | } | ||
475 | OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); | ||
476 | OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); | ||
477 | /* SQ config */ | ||
478 | OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6)); | ||
479 | OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2); | ||
480 | OUT_RING(sq_config); | ||
481 | OUT_RING(sq_gpr_resource_mgmt_1); | ||
482 | OUT_RING(sq_gpr_resource_mgmt_2); | ||
483 | OUT_RING(sq_thread_resource_mgmt); | ||
484 | OUT_RING(sq_stack_resource_mgmt_1); | ||
485 | OUT_RING(sq_stack_resource_mgmt_2); | ||
486 | ADVANCE_RING(); | ||
487 | } | ||
488 | |||
489 | static inline uint32_t i2f(uint32_t input) | ||
490 | { | ||
491 | u32 result, i, exponent, fraction; | ||
492 | |||
493 | if ((input & 0x3fff) == 0) | ||
494 | result = 0; /* 0 is a special case */ | ||
495 | else { | ||
496 | exponent = 140; /* exponent biased by 127; */ | ||
497 | fraction = (input & 0x3fff) << 10; /* cheat and only | ||
498 | handle numbers below 2^^15 */ | ||
499 | for (i = 0; i < 14; i++) { | ||
500 | if (fraction & 0x800000) | ||
501 | break; | ||
502 | else { | ||
503 | fraction = fraction << 1; /* keep | ||
504 | shifting left until top bit = 1 */ | ||
505 | exponent = exponent - 1; | ||
506 | } | ||
507 | } | ||
508 | result = exponent << 23 | (fraction & 0x7fffff); /* mask | ||
509 | off top bit; assumed 1 */ | ||
510 | } | ||
511 | return result; | ||
512 | } | ||
513 | |||
514 | |||
515 | int r600_nomm_get_vb(struct drm_device *dev) | ||
516 | { | ||
517 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
518 | dev_priv->blit_vb = radeon_freelist_get(dev); | ||
519 | if (!dev_priv->blit_vb) { | ||
520 | DRM_ERROR("Unable to allocate vertex buffer for blit\n"); | ||
521 | return -EAGAIN; | ||
522 | } | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | void r600_nomm_put_vb(struct drm_device *dev) | ||
527 | { | ||
528 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
529 | |||
530 | dev_priv->blit_vb->used = 0; | ||
531 | radeon_cp_discard_buffer(dev, dev_priv->blit_vb->file_priv->master, dev_priv->blit_vb); | ||
532 | } | ||
533 | |||
534 | void *r600_nomm_get_vb_ptr(struct drm_device *dev) | ||
535 | { | ||
536 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
537 | return (((char *)dev->agp_buffer_map->handle + | ||
538 | dev_priv->blit_vb->offset + dev_priv->blit_vb->used)); | ||
539 | } | ||
540 | |||
541 | int | ||
542 | r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv) | ||
543 | { | ||
544 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
545 | DRM_DEBUG("\n"); | ||
546 | |||
547 | r600_nomm_get_vb(dev); | ||
548 | |||
549 | dev_priv->blit_vb->file_priv = file_priv; | ||
550 | |||
551 | set_default_state(dev_priv); | ||
552 | set_shaders(dev); | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | |||
558 | void | ||
559 | r600_done_blit_copy(struct drm_device *dev) | ||
560 | { | ||
561 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
562 | RING_LOCALS; | ||
563 | DRM_DEBUG("\n"); | ||
564 | |||
565 | BEGIN_RING(5); | ||
566 | OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); | ||
567 | OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); | ||
568 | /* wait for 3D idle clean */ | ||
569 | OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); | ||
570 | OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); | ||
571 | OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); | ||
572 | |||
573 | ADVANCE_RING(); | ||
574 | COMMIT_RING(); | ||
575 | |||
576 | r600_nomm_put_vb(dev); | ||
577 | } | ||
578 | |||
579 | void | ||
580 | r600_blit_copy(struct drm_device *dev, | ||
581 | uint64_t src_gpu_addr, uint64_t dst_gpu_addr, | ||
582 | int size_bytes) | ||
583 | { | ||
584 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
585 | int max_bytes; | ||
586 | u64 vb_addr; | ||
587 | u32 *vb; | ||
588 | |||
589 | vb = r600_nomm_get_vb_ptr(dev); | ||
590 | |||
591 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { | ||
592 | max_bytes = 8192; | ||
593 | |||
594 | while (size_bytes) { | ||
595 | int cur_size = size_bytes; | ||
596 | int src_x = src_gpu_addr & 255; | ||
597 | int dst_x = dst_gpu_addr & 255; | ||
598 | int h = 1; | ||
599 | src_gpu_addr = src_gpu_addr & ~255; | ||
600 | dst_gpu_addr = dst_gpu_addr & ~255; | ||
601 | |||
602 | if (!src_x && !dst_x) { | ||
603 | h = (cur_size / max_bytes); | ||
604 | if (h > 8192) | ||
605 | h = 8192; | ||
606 | if (h == 0) | ||
607 | h = 1; | ||
608 | else | ||
609 | cur_size = max_bytes; | ||
610 | } else { | ||
611 | if (cur_size > max_bytes) | ||
612 | cur_size = max_bytes; | ||
613 | if (cur_size > (max_bytes - dst_x)) | ||
614 | cur_size = (max_bytes - dst_x); | ||
615 | if (cur_size > (max_bytes - src_x)) | ||
616 | cur_size = (max_bytes - src_x); | ||
617 | } | ||
618 | |||
619 | if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { | ||
620 | |||
621 | r600_nomm_put_vb(dev); | ||
622 | r600_nomm_get_vb(dev); | ||
623 | if (!dev_priv->blit_vb) | ||
624 | return; | ||
625 | set_shaders(dev); | ||
626 | vb = r600_nomm_get_vb_ptr(dev); | ||
627 | } | ||
628 | |||
629 | vb[0] = i2f(dst_x); | ||
630 | vb[1] = 0; | ||
631 | vb[2] = i2f(src_x); | ||
632 | vb[3] = 0; | ||
633 | |||
634 | vb[4] = i2f(dst_x); | ||
635 | vb[5] = i2f(h); | ||
636 | vb[6] = i2f(src_x); | ||
637 | vb[7] = i2f(h); | ||
638 | |||
639 | vb[8] = i2f(dst_x + cur_size); | ||
640 | vb[9] = i2f(h); | ||
641 | vb[10] = i2f(src_x + cur_size); | ||
642 | vb[11] = i2f(h); | ||
643 | |||
644 | /* src */ | ||
645 | set_tex_resource(dev_priv, FMT_8, | ||
646 | src_x + cur_size, h, src_x + cur_size, | ||
647 | src_gpu_addr); | ||
648 | |||
649 | cp_set_surface_sync(dev_priv, | ||
650 | R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); | ||
651 | |||
652 | /* dst */ | ||
653 | set_render_target(dev_priv, COLOR_8, | ||
654 | dst_x + cur_size, h, | ||
655 | dst_gpu_addr); | ||
656 | |||
657 | /* scissors */ | ||
658 | set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h); | ||
659 | |||
660 | /* Vertex buffer setup */ | ||
661 | vb_addr = dev_priv->gart_buffers_offset + | ||
662 | dev_priv->blit_vb->offset + | ||
663 | dev_priv->blit_vb->used; | ||
664 | set_vtx_resource(dev_priv, vb_addr); | ||
665 | |||
666 | /* draw */ | ||
667 | draw_auto(dev_priv); | ||
668 | |||
669 | cp_set_surface_sync(dev_priv, | ||
670 | R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, | ||
671 | cur_size * h, dst_gpu_addr); | ||
672 | |||
673 | vb += 12; | ||
674 | dev_priv->blit_vb->used += 12 * 4; | ||
675 | |||
676 | src_gpu_addr += cur_size * h; | ||
677 | dst_gpu_addr += cur_size * h; | ||
678 | size_bytes -= cur_size * h; | ||
679 | } | ||
680 | } else { | ||
681 | max_bytes = 8192 * 4; | ||
682 | |||
683 | while (size_bytes) { | ||
684 | int cur_size = size_bytes; | ||
685 | int src_x = (src_gpu_addr & 255); | ||
686 | int dst_x = (dst_gpu_addr & 255); | ||
687 | int h = 1; | ||
688 | src_gpu_addr = src_gpu_addr & ~255; | ||
689 | dst_gpu_addr = dst_gpu_addr & ~255; | ||
690 | |||
691 | if (!src_x && !dst_x) { | ||
692 | h = (cur_size / max_bytes); | ||
693 | if (h > 8192) | ||
694 | h = 8192; | ||
695 | if (h == 0) | ||
696 | h = 1; | ||
697 | else | ||
698 | cur_size = max_bytes; | ||
699 | } else { | ||
700 | if (cur_size > max_bytes) | ||
701 | cur_size = max_bytes; | ||
702 | if (cur_size > (max_bytes - dst_x)) | ||
703 | cur_size = (max_bytes - dst_x); | ||
704 | if (cur_size > (max_bytes - src_x)) | ||
705 | cur_size = (max_bytes - src_x); | ||
706 | } | ||
707 | |||
708 | if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { | ||
709 | r600_nomm_put_vb(dev); | ||
710 | r600_nomm_get_vb(dev); | ||
711 | if (!dev_priv->blit_vb) | ||
712 | return; | ||
713 | |||
714 | set_shaders(dev); | ||
715 | vb = r600_nomm_get_vb_ptr(dev); | ||
716 | } | ||
717 | |||
718 | vb[0] = i2f(dst_x / 4); | ||
719 | vb[1] = 0; | ||
720 | vb[2] = i2f(src_x / 4); | ||
721 | vb[3] = 0; | ||
722 | |||
723 | vb[4] = i2f(dst_x / 4); | ||
724 | vb[5] = i2f(h); | ||
725 | vb[6] = i2f(src_x / 4); | ||
726 | vb[7] = i2f(h); | ||
727 | |||
728 | vb[8] = i2f((dst_x + cur_size) / 4); | ||
729 | vb[9] = i2f(h); | ||
730 | vb[10] = i2f((src_x + cur_size) / 4); | ||
731 | vb[11] = i2f(h); | ||
732 | |||
733 | /* src */ | ||
734 | set_tex_resource(dev_priv, FMT_8_8_8_8, | ||
735 | (src_x + cur_size) / 4, | ||
736 | h, (src_x + cur_size) / 4, | ||
737 | src_gpu_addr); | ||
738 | |||
739 | cp_set_surface_sync(dev_priv, | ||
740 | R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); | ||
741 | |||
742 | /* dst */ | ||
743 | set_render_target(dev_priv, COLOR_8_8_8_8, | ||
744 | dst_x + cur_size, h, | ||
745 | dst_gpu_addr); | ||
746 | |||
747 | /* scissors */ | ||
748 | set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h); | ||
749 | |||
750 | /* Vertex buffer setup */ | ||
751 | vb_addr = dev_priv->gart_buffers_offset + | ||
752 | dev_priv->blit_vb->offset + | ||
753 | dev_priv->blit_vb->used; | ||
754 | set_vtx_resource(dev_priv, vb_addr); | ||
755 | |||
756 | /* draw */ | ||
757 | draw_auto(dev_priv); | ||
758 | |||
759 | cp_set_surface_sync(dev_priv, | ||
760 | R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, | ||
761 | cur_size * h, dst_gpu_addr); | ||
762 | |||
763 | vb += 12; | ||
764 | dev_priv->blit_vb->used += 12 * 4; | ||
765 | |||
766 | src_gpu_addr += cur_size * h; | ||
767 | dst_gpu_addr += cur_size * h; | ||
768 | size_bytes -= cur_size * h; | ||
769 | } | ||
770 | } | ||
771 | } | ||
772 | |||
773 | void | ||
774 | r600_blit_swap(struct drm_device *dev, | ||
775 | uint64_t src_gpu_addr, uint64_t dst_gpu_addr, | ||
776 | int sx, int sy, int dx, int dy, | ||
777 | int w, int h, int src_pitch, int dst_pitch, int cpp) | ||
778 | { | ||
779 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
780 | int cb_format, tex_format; | ||
781 | u64 vb_addr; | ||
782 | u32 *vb; | ||
783 | |||
784 | vb = (u32 *) ((char *)dev->agp_buffer_map->handle + | ||
785 | dev_priv->blit_vb->offset + dev_priv->blit_vb->used); | ||
786 | |||
787 | if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { | ||
788 | |||
789 | r600_nomm_put_vb(dev); | ||
790 | r600_nomm_get_vb(dev); | ||
791 | if (!dev_priv->blit_vb) | ||
792 | return; | ||
793 | |||
794 | set_shaders(dev); | ||
795 | vb = r600_nomm_get_vb_ptr(dev); | ||
796 | } | ||
797 | |||
798 | if (cpp == 4) { | ||
799 | cb_format = COLOR_8_8_8_8; | ||
800 | tex_format = FMT_8_8_8_8; | ||
801 | } else if (cpp == 2) { | ||
802 | cb_format = COLOR_5_6_5; | ||
803 | tex_format = FMT_5_6_5; | ||
804 | } else { | ||
805 | cb_format = COLOR_8; | ||
806 | tex_format = FMT_8; | ||
807 | } | ||
808 | |||
809 | vb[0] = i2f(dx); | ||
810 | vb[1] = i2f(dy); | ||
811 | vb[2] = i2f(sx); | ||
812 | vb[3] = i2f(sy); | ||
813 | |||
814 | vb[4] = i2f(dx); | ||
815 | vb[5] = i2f(dy + h); | ||
816 | vb[6] = i2f(sx); | ||
817 | vb[7] = i2f(sy + h); | ||
818 | |||
819 | vb[8] = i2f(dx + w); | ||
820 | vb[9] = i2f(dy + h); | ||
821 | vb[10] = i2f(sx + w); | ||
822 | vb[11] = i2f(sy + h); | ||
823 | |||
824 | /* src */ | ||
825 | set_tex_resource(dev_priv, tex_format, | ||
826 | src_pitch / cpp, | ||
827 | sy + h, src_pitch / cpp, | ||
828 | src_gpu_addr); | ||
829 | |||
830 | cp_set_surface_sync(dev_priv, | ||
831 | R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr); | ||
832 | |||
833 | /* dst */ | ||
834 | set_render_target(dev_priv, cb_format, | ||
835 | dst_pitch / cpp, dy + h, | ||
836 | dst_gpu_addr); | ||
837 | |||
838 | /* scissors */ | ||
839 | set_scissors(dev_priv, dx, dy, dx + w, dy + h); | ||
840 | |||
841 | /* Vertex buffer setup */ | ||
842 | vb_addr = dev_priv->gart_buffers_offset + | ||
843 | dev_priv->blit_vb->offset + | ||
844 | dev_priv->blit_vb->used; | ||
845 | set_vtx_resource(dev_priv, vb_addr); | ||
846 | |||
847 | /* draw */ | ||
848 | draw_auto(dev_priv); | ||
849 | |||
850 | cp_set_surface_sync(dev_priv, | ||
851 | R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, | ||
852 | dst_pitch * (dy + h), dst_gpu_addr); | ||
853 | |||
854 | dev_priv->blit_vb->used += 12 * 4; | ||
855 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c new file mode 100644 index 000000000000..5755647e688a --- /dev/null +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -0,0 +1,777 @@ | |||
1 | #include "drmP.h" | ||
2 | #include "drm.h" | ||
3 | #include "radeon_drm.h" | ||
4 | #include "radeon.h" | ||
5 | |||
6 | #include "r600d.h" | ||
7 | #include "r600_blit_shaders.h" | ||
8 | |||
9 | #define DI_PT_RECTLIST 0x11 | ||
10 | #define DI_INDEX_SIZE_16_BIT 0x0 | ||
11 | #define DI_SRC_SEL_AUTO_INDEX 0x2 | ||
12 | |||
13 | #define FMT_8 0x1 | ||
14 | #define FMT_5_6_5 0x8 | ||
15 | #define FMT_8_8_8_8 0x1a | ||
16 | #define COLOR_8 0x1 | ||
17 | #define COLOR_5_6_5 0x8 | ||
18 | #define COLOR_8_8_8_8 0x1a | ||
19 | |||
20 | /* emits 21 on rv770+, 23 on r600 */ | ||
21 | static void | ||
22 | set_render_target(struct radeon_device *rdev, int format, | ||
23 | int w, int h, u64 gpu_addr) | ||
24 | { | ||
25 | u32 cb_color_info; | ||
26 | int pitch, slice; | ||
27 | |||
28 | h = (h + 7) & ~7; | ||
29 | if (h < 8) | ||
30 | h = 8; | ||
31 | |||
32 | cb_color_info = ((format << 2) | (1 << 27)); | ||
33 | pitch = (w / 8) - 1; | ||
34 | slice = ((w * h) / 64) - 1; | ||
35 | |||
36 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
37 | radeon_ring_write(rdev, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
38 | radeon_ring_write(rdev, gpu_addr >> 8); | ||
39 | |||
40 | if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) { | ||
41 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0)); | ||
42 | radeon_ring_write(rdev, 2 << 0); | ||
43 | } | ||
44 | |||
45 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
46 | radeon_ring_write(rdev, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
47 | radeon_ring_write(rdev, (pitch << 0) | (slice << 10)); | ||
48 | |||
49 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
50 | radeon_ring_write(rdev, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
51 | radeon_ring_write(rdev, 0); | ||
52 | |||
53 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
54 | radeon_ring_write(rdev, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
55 | radeon_ring_write(rdev, cb_color_info); | ||
56 | |||
57 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
58 | radeon_ring_write(rdev, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
59 | radeon_ring_write(rdev, 0); | ||
60 | |||
61 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
62 | radeon_ring_write(rdev, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
63 | radeon_ring_write(rdev, 0); | ||
64 | |||
65 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
66 | radeon_ring_write(rdev, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
67 | radeon_ring_write(rdev, 0); | ||
68 | } | ||
69 | |||
70 | /* emits 5dw */ | ||
71 | static void | ||
72 | cp_set_surface_sync(struct radeon_device *rdev, | ||
73 | u32 sync_type, u32 size, | ||
74 | u64 mc_addr) | ||
75 | { | ||
76 | u32 cp_coher_size; | ||
77 | |||
78 | if (size == 0xffffffff) | ||
79 | cp_coher_size = 0xffffffff; | ||
80 | else | ||
81 | cp_coher_size = ((size + 255) >> 8); | ||
82 | |||
83 | radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); | ||
84 | radeon_ring_write(rdev, sync_type); | ||
85 | radeon_ring_write(rdev, cp_coher_size); | ||
86 | radeon_ring_write(rdev, mc_addr >> 8); | ||
87 | radeon_ring_write(rdev, 10); /* poll interval */ | ||
88 | } | ||
89 | |||
90 | /* emits 21dw + 1 surface sync = 26dw */ | ||
91 | static void | ||
92 | set_shaders(struct radeon_device *rdev) | ||
93 | { | ||
94 | u64 gpu_addr; | ||
95 | u32 sq_pgm_resources; | ||
96 | |||
97 | /* setup shader regs */ | ||
98 | sq_pgm_resources = (1 << 0); | ||
99 | |||
100 | /* VS */ | ||
101 | gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; | ||
102 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
103 | radeon_ring_write(rdev, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
104 | radeon_ring_write(rdev, gpu_addr >> 8); | ||
105 | |||
106 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
107 | radeon_ring_write(rdev, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
108 | radeon_ring_write(rdev, sq_pgm_resources); | ||
109 | |||
110 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
111 | radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
112 | radeon_ring_write(rdev, 0); | ||
113 | |||
114 | /* PS */ | ||
115 | gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; | ||
116 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
117 | radeon_ring_write(rdev, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
118 | radeon_ring_write(rdev, gpu_addr >> 8); | ||
119 | |||
120 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
121 | radeon_ring_write(rdev, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
122 | radeon_ring_write(rdev, sq_pgm_resources | (1 << 28)); | ||
123 | |||
124 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
125 | radeon_ring_write(rdev, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
126 | radeon_ring_write(rdev, 2); | ||
127 | |||
128 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); | ||
129 | radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
130 | radeon_ring_write(rdev, 0); | ||
131 | |||
132 | cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); | ||
133 | } | ||
134 | |||
135 | /* emits 9 + 1 sync (5) = 14*/ | ||
136 | static void | ||
137 | set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) | ||
138 | { | ||
139 | u32 sq_vtx_constant_word2; | ||
140 | |||
141 | sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); | ||
142 | |||
143 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); | ||
144 | radeon_ring_write(rdev, 0x460); | ||
145 | radeon_ring_write(rdev, gpu_addr & 0xffffffff); | ||
146 | radeon_ring_write(rdev, 48 - 1); | ||
147 | radeon_ring_write(rdev, sq_vtx_constant_word2); | ||
148 | radeon_ring_write(rdev, 1 << 0); | ||
149 | radeon_ring_write(rdev, 0); | ||
150 | radeon_ring_write(rdev, 0); | ||
151 | radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30); | ||
152 | |||
153 | if ((rdev->family == CHIP_RV610) || | ||
154 | (rdev->family == CHIP_RV620) || | ||
155 | (rdev->family == CHIP_RS780) || | ||
156 | (rdev->family == CHIP_RS880) || | ||
157 | (rdev->family == CHIP_RV710)) | ||
158 | cp_set_surface_sync(rdev, | ||
159 | PACKET3_TC_ACTION_ENA, 48, gpu_addr); | ||
160 | else | ||
161 | cp_set_surface_sync(rdev, | ||
162 | PACKET3_VC_ACTION_ENA, 48, gpu_addr); | ||
163 | } | ||
164 | |||
165 | /* emits 9 */ | ||
166 | static void | ||
167 | set_tex_resource(struct radeon_device *rdev, | ||
168 | int format, int w, int h, int pitch, | ||
169 | u64 gpu_addr) | ||
170 | { | ||
171 | uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; | ||
172 | |||
173 | if (h < 1) | ||
174 | h = 1; | ||
175 | |||
176 | sq_tex_resource_word0 = (1 << 0); | ||
177 | sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | | ||
178 | ((w - 1) << 19)); | ||
179 | |||
180 | sq_tex_resource_word1 = (format << 26); | ||
181 | sq_tex_resource_word1 |= ((h - 1) << 0); | ||
182 | |||
183 | sq_tex_resource_word4 = ((1 << 14) | | ||
184 | (0 << 16) | | ||
185 | (1 << 19) | | ||
186 | (2 << 22) | | ||
187 | (3 << 25)); | ||
188 | |||
189 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); | ||
190 | radeon_ring_write(rdev, 0); | ||
191 | radeon_ring_write(rdev, sq_tex_resource_word0); | ||
192 | radeon_ring_write(rdev, sq_tex_resource_word1); | ||
193 | radeon_ring_write(rdev, gpu_addr >> 8); | ||
194 | radeon_ring_write(rdev, gpu_addr >> 8); | ||
195 | radeon_ring_write(rdev, sq_tex_resource_word4); | ||
196 | radeon_ring_write(rdev, 0); | ||
197 | radeon_ring_write(rdev, SQ_TEX_VTX_VALID_TEXTURE << 30); | ||
198 | } | ||
199 | |||
200 | /* emits 12 */ | ||
201 | static void | ||
202 | set_scissors(struct radeon_device *rdev, int x1, int y1, | ||
203 | int x2, int y2) | ||
204 | { | ||
205 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); | ||
206 | radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
207 | radeon_ring_write(rdev, (x1 << 0) | (y1 << 16)); | ||
208 | radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); | ||
209 | |||
210 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); | ||
211 | radeon_ring_write(rdev, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
212 | radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); | ||
213 | radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); | ||
214 | |||
215 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); | ||
216 | radeon_ring_write(rdev, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); | ||
217 | radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); | ||
218 | radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); | ||
219 | } | ||
220 | |||
221 | /* emits 10 */ | ||
222 | static void | ||
223 | draw_auto(struct radeon_device *rdev) | ||
224 | { | ||
225 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
226 | radeon_ring_write(rdev, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | ||
227 | radeon_ring_write(rdev, DI_PT_RECTLIST); | ||
228 | |||
229 | radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); | ||
230 | radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); | ||
231 | |||
232 | radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); | ||
233 | radeon_ring_write(rdev, 1); | ||
234 | |||
235 | radeon_ring_write(rdev, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); | ||
236 | radeon_ring_write(rdev, 3); | ||
237 | radeon_ring_write(rdev, DI_SRC_SEL_AUTO_INDEX); | ||
238 | |||
239 | } | ||
240 | |||
241 | /* emits 14 */ | ||
242 | static void | ||
243 | set_default_state(struct radeon_device *rdev) | ||
244 | { | ||
245 | u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; | ||
246 | u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; | ||
247 | int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; | ||
248 | int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; | ||
249 | int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; | ||
250 | u64 gpu_addr; | ||
251 | |||
252 | switch (rdev->family) { | ||
253 | case CHIP_R600: | ||
254 | num_ps_gprs = 192; | ||
255 | num_vs_gprs = 56; | ||
256 | num_temp_gprs = 4; | ||
257 | num_gs_gprs = 0; | ||
258 | num_es_gprs = 0; | ||
259 | num_ps_threads = 136; | ||
260 | num_vs_threads = 48; | ||
261 | num_gs_threads = 4; | ||
262 | num_es_threads = 4; | ||
263 | num_ps_stack_entries = 128; | ||
264 | num_vs_stack_entries = 128; | ||
265 | num_gs_stack_entries = 0; | ||
266 | num_es_stack_entries = 0; | ||
267 | break; | ||
268 | case CHIP_RV630: | ||
269 | case CHIP_RV635: | ||
270 | num_ps_gprs = 84; | ||
271 | num_vs_gprs = 36; | ||
272 | num_temp_gprs = 4; | ||
273 | num_gs_gprs = 0; | ||
274 | num_es_gprs = 0; | ||
275 | num_ps_threads = 144; | ||
276 | num_vs_threads = 40; | ||
277 | num_gs_threads = 4; | ||
278 | num_es_threads = 4; | ||
279 | num_ps_stack_entries = 40; | ||
280 | num_vs_stack_entries = 40; | ||
281 | num_gs_stack_entries = 32; | ||
282 | num_es_stack_entries = 16; | ||
283 | break; | ||
284 | case CHIP_RV610: | ||
285 | case CHIP_RV620: | ||
286 | case CHIP_RS780: | ||
287 | case CHIP_RS880: | ||
288 | default: | ||
289 | num_ps_gprs = 84; | ||
290 | num_vs_gprs = 36; | ||
291 | num_temp_gprs = 4; | ||
292 | num_gs_gprs = 0; | ||
293 | num_es_gprs = 0; | ||
294 | num_ps_threads = 136; | ||
295 | num_vs_threads = 48; | ||
296 | num_gs_threads = 4; | ||
297 | num_es_threads = 4; | ||
298 | num_ps_stack_entries = 40; | ||
299 | num_vs_stack_entries = 40; | ||
300 | num_gs_stack_entries = 32; | ||
301 | num_es_stack_entries = 16; | ||
302 | break; | ||
303 | case CHIP_RV670: | ||
304 | num_ps_gprs = 144; | ||
305 | num_vs_gprs = 40; | ||
306 | num_temp_gprs = 4; | ||
307 | num_gs_gprs = 0; | ||
308 | num_es_gprs = 0; | ||
309 | num_ps_threads = 136; | ||
310 | num_vs_threads = 48; | ||
311 | num_gs_threads = 4; | ||
312 | num_es_threads = 4; | ||
313 | num_ps_stack_entries = 40; | ||
314 | num_vs_stack_entries = 40; | ||
315 | num_gs_stack_entries = 32; | ||
316 | num_es_stack_entries = 16; | ||
317 | break; | ||
318 | case CHIP_RV770: | ||
319 | num_ps_gprs = 192; | ||
320 | num_vs_gprs = 56; | ||
321 | num_temp_gprs = 4; | ||
322 | num_gs_gprs = 0; | ||
323 | num_es_gprs = 0; | ||
324 | num_ps_threads = 188; | ||
325 | num_vs_threads = 60; | ||
326 | num_gs_threads = 0; | ||
327 | num_es_threads = 0; | ||
328 | num_ps_stack_entries = 256; | ||
329 | num_vs_stack_entries = 256; | ||
330 | num_gs_stack_entries = 0; | ||
331 | num_es_stack_entries = 0; | ||
332 | break; | ||
333 | case CHIP_RV730: | ||
334 | case CHIP_RV740: | ||
335 | num_ps_gprs = 84; | ||
336 | num_vs_gprs = 36; | ||
337 | num_temp_gprs = 4; | ||
338 | num_gs_gprs = 0; | ||
339 | num_es_gprs = 0; | ||
340 | num_ps_threads = 188; | ||
341 | num_vs_threads = 60; | ||
342 | num_gs_threads = 0; | ||
343 | num_es_threads = 0; | ||
344 | num_ps_stack_entries = 128; | ||
345 | num_vs_stack_entries = 128; | ||
346 | num_gs_stack_entries = 0; | ||
347 | num_es_stack_entries = 0; | ||
348 | break; | ||
349 | case CHIP_RV710: | ||
350 | num_ps_gprs = 192; | ||
351 | num_vs_gprs = 56; | ||
352 | num_temp_gprs = 4; | ||
353 | num_gs_gprs = 0; | ||
354 | num_es_gprs = 0; | ||
355 | num_ps_threads = 144; | ||
356 | num_vs_threads = 48; | ||
357 | num_gs_threads = 0; | ||
358 | num_es_threads = 0; | ||
359 | num_ps_stack_entries = 128; | ||
360 | num_vs_stack_entries = 128; | ||
361 | num_gs_stack_entries = 0; | ||
362 | num_es_stack_entries = 0; | ||
363 | break; | ||
364 | } | ||
365 | |||
366 | if ((rdev->family == CHIP_RV610) || | ||
367 | (rdev->family == CHIP_RV620) || | ||
368 | (rdev->family == CHIP_RS780) || | ||
369 | (rdev->family == CHIP_RS780) || | ||
370 | (rdev->family == CHIP_RV710)) | ||
371 | sq_config = 0; | ||
372 | else | ||
373 | sq_config = VC_ENABLE; | ||
374 | |||
375 | sq_config |= (DX9_CONSTS | | ||
376 | ALU_INST_PREFER_VECTOR | | ||
377 | PS_PRIO(0) | | ||
378 | VS_PRIO(1) | | ||
379 | GS_PRIO(2) | | ||
380 | ES_PRIO(3)); | ||
381 | |||
382 | sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | | ||
383 | NUM_VS_GPRS(num_vs_gprs) | | ||
384 | NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); | ||
385 | sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | | ||
386 | NUM_ES_GPRS(num_es_gprs)); | ||
387 | sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | | ||
388 | NUM_VS_THREADS(num_vs_threads) | | ||
389 | NUM_GS_THREADS(num_gs_threads) | | ||
390 | NUM_ES_THREADS(num_es_threads)); | ||
391 | sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | | ||
392 | NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); | ||
393 | sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | | ||
394 | NUM_ES_STACK_ENTRIES(num_es_stack_entries)); | ||
395 | |||
396 | /* emit an IB pointing at default state */ | ||
397 | gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; | ||
398 | radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); | ||
399 | radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC); | ||
400 | radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); | ||
401 | radeon_ring_write(rdev, (rdev->r600_blit.state_len / 4)); | ||
402 | |||
403 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | ||
404 | radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); | ||
405 | /* SQ config */ | ||
406 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 6)); | ||
407 | radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | ||
408 | radeon_ring_write(rdev, sq_config); | ||
409 | radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); | ||
410 | radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); | ||
411 | radeon_ring_write(rdev, sq_thread_resource_mgmt); | ||
412 | radeon_ring_write(rdev, sq_stack_resource_mgmt_1); | ||
413 | radeon_ring_write(rdev, sq_stack_resource_mgmt_2); | ||
414 | } | ||
415 | |||
416 | static inline uint32_t i2f(uint32_t input) | ||
417 | { | ||
418 | u32 result, i, exponent, fraction; | ||
419 | |||
420 | if ((input & 0x3fff) == 0) | ||
421 | result = 0; /* 0 is a special case */ | ||
422 | else { | ||
423 | exponent = 140; /* exponent biased by 127; */ | ||
424 | fraction = (input & 0x3fff) << 10; /* cheat and only | ||
425 | handle numbers below 2^^15 */ | ||
426 | for (i = 0; i < 14; i++) { | ||
427 | if (fraction & 0x800000) | ||
428 | break; | ||
429 | else { | ||
430 | fraction = fraction << 1; /* keep | ||
431 | shifting left until top bit = 1 */ | ||
432 | exponent = exponent - 1; | ||
433 | } | ||
434 | } | ||
435 | result = exponent << 23 | (fraction & 0x7fffff); /* mask | ||
436 | off top bit; assumed 1 */ | ||
437 | } | ||
438 | return result; | ||
439 | } | ||
440 | |||
441 | int r600_blit_init(struct radeon_device *rdev) | ||
442 | { | ||
443 | u32 obj_size; | ||
444 | int r; | ||
445 | void *ptr; | ||
446 | |||
447 | rdev->r600_blit.state_offset = 0; | ||
448 | |||
449 | if (rdev->family >= CHIP_RV770) | ||
450 | rdev->r600_blit.state_len = r7xx_default_size * 4; | ||
451 | else | ||
452 | rdev->r600_blit.state_len = r6xx_default_size * 4; | ||
453 | |||
454 | obj_size = rdev->r600_blit.state_len; | ||
455 | obj_size = ALIGN(obj_size, 256); | ||
456 | |||
457 | rdev->r600_blit.vs_offset = obj_size; | ||
458 | obj_size += r6xx_vs_size * 4; | ||
459 | obj_size = ALIGN(obj_size, 256); | ||
460 | |||
461 | rdev->r600_blit.ps_offset = obj_size; | ||
462 | obj_size += r6xx_ps_size * 4; | ||
463 | obj_size = ALIGN(obj_size, 256); | ||
464 | |||
465 | r = radeon_object_create(rdev, NULL, obj_size, | ||
466 | true, RADEON_GEM_DOMAIN_VRAM, | ||
467 | false, &rdev->r600_blit.shader_obj); | ||
468 | if (r) { | ||
469 | DRM_ERROR("r600 failed to allocate shader\n"); | ||
470 | return r; | ||
471 | } | ||
472 | |||
473 | r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
474 | &rdev->r600_blit.shader_gpu_addr); | ||
475 | if (r) { | ||
476 | DRM_ERROR("failed to pin blit object %d\n", r); | ||
477 | return r; | ||
478 | } | ||
479 | |||
480 | DRM_DEBUG("r6xx blit allocated bo @ 0x%16llx %08x vs %08x ps %08x\n", | ||
481 | rdev->r600_blit.shader_gpu_addr, obj_size, | ||
482 | rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset); | ||
483 | |||
484 | r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr); | ||
485 | if (r) { | ||
486 | DRM_ERROR("failed to map blit object %d\n", r); | ||
487 | return r; | ||
488 | } | ||
489 | |||
490 | if (rdev->family >= CHIP_RV770) | ||
491 | memcpy_toio(ptr + rdev->r600_blit.state_offset, r7xx_default_state, rdev->r600_blit.state_len); | ||
492 | else | ||
493 | memcpy_toio(ptr + rdev->r600_blit.state_offset, r6xx_default_state, rdev->r600_blit.state_len); | ||
494 | |||
495 | memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); | ||
496 | memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); | ||
497 | |||
498 | radeon_object_kunmap(rdev->r600_blit.shader_obj); | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | void r600_blit_fini(struct radeon_device *rdev) | ||
503 | { | ||
504 | radeon_object_unpin(rdev->r600_blit.shader_obj); | ||
505 | radeon_object_unref(&rdev->r600_blit.shader_obj); | ||
506 | } | ||
507 | |||
508 | int r600_vb_ib_get(struct radeon_device *rdev) | ||
509 | { | ||
510 | int r; | ||
511 | r = radeon_ib_get(rdev, &rdev->r600_blit.vb_ib); | ||
512 | if (r) { | ||
513 | DRM_ERROR("failed to get IB for vertex buffer\n"); | ||
514 | return r; | ||
515 | } | ||
516 | |||
517 | rdev->r600_blit.vb_total = 64*1024; | ||
518 | rdev->r600_blit.vb_used = 0; | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | void r600_vb_ib_put(struct radeon_device *rdev) | ||
523 | { | ||
524 | mutex_lock(&rdev->ib_pool.mutex); | ||
525 | radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); | ||
526 | list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs); | ||
527 | mutex_unlock(&rdev->ib_pool.mutex); | ||
528 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | ||
529 | } | ||
530 | |||
531 | int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | ||
532 | { | ||
533 | int r; | ||
534 | int ring_size; | ||
535 | const int max_size = 8192*8192; | ||
536 | |||
537 | r = r600_vb_ib_get(rdev); | ||
538 | WARN_ON(r); | ||
539 | |||
540 | /* loops of emits 64 + fence emit possible */ | ||
541 | ring_size = ((size_bytes + max_size) / max_size) * 78; | ||
542 | /* set default + shaders */ | ||
543 | ring_size += 40; /* shaders + def state */ | ||
544 | ring_size += 3; /* fence emit for VB IB */ | ||
545 | ring_size += 5; /* done copy */ | ||
546 | ring_size += 3; /* fence emit for done copy */ | ||
547 | r = radeon_ring_lock(rdev, ring_size); | ||
548 | WARN_ON(r); | ||
549 | |||
550 | set_default_state(rdev); /* 14 */ | ||
551 | set_shaders(rdev); /* 26 */ | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence) | ||
556 | { | ||
557 | int r; | ||
558 | |||
559 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | ||
560 | radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); | ||
561 | /* wait for 3D idle clean */ | ||
562 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
563 | radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | ||
564 | radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); | ||
565 | |||
566 | if (rdev->r600_blit.vb_ib) | ||
567 | r600_vb_ib_put(rdev); | ||
568 | |||
569 | if (fence) | ||
570 | r = radeon_fence_emit(rdev, fence); | ||
571 | |||
572 | radeon_ring_unlock_commit(rdev); | ||
573 | } | ||
574 | |||
575 | void r600_kms_blit_copy(struct radeon_device *rdev, | ||
576 | u64 src_gpu_addr, u64 dst_gpu_addr, | ||
577 | int size_bytes) | ||
578 | { | ||
579 | int max_bytes; | ||
580 | u64 vb_gpu_addr; | ||
581 | u32 *vb; | ||
582 | |||
583 | DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, | ||
584 | size_bytes, rdev->r600_blit.vb_used); | ||
585 | vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); | ||
586 | if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { | ||
587 | max_bytes = 8192; | ||
588 | |||
589 | while (size_bytes) { | ||
590 | int cur_size = size_bytes; | ||
591 | int src_x = src_gpu_addr & 255; | ||
592 | int dst_x = dst_gpu_addr & 255; | ||
593 | int h = 1; | ||
594 | src_gpu_addr = src_gpu_addr & ~255; | ||
595 | dst_gpu_addr = dst_gpu_addr & ~255; | ||
596 | |||
597 | if (!src_x && !dst_x) { | ||
598 | h = (cur_size / max_bytes); | ||
599 | if (h > 8192) | ||
600 | h = 8192; | ||
601 | if (h == 0) | ||
602 | h = 1; | ||
603 | else | ||
604 | cur_size = max_bytes; | ||
605 | } else { | ||
606 | if (cur_size > max_bytes) | ||
607 | cur_size = max_bytes; | ||
608 | if (cur_size > (max_bytes - dst_x)) | ||
609 | cur_size = (max_bytes - dst_x); | ||
610 | if (cur_size > (max_bytes - src_x)) | ||
611 | cur_size = (max_bytes - src_x); | ||
612 | } | ||
613 | |||
614 | if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { | ||
615 | WARN_ON(1); | ||
616 | |||
617 | #if 0 | ||
618 | r600_vb_ib_put(rdev); | ||
619 | |||
620 | r600_nomm_put_vb(dev); | ||
621 | r600_nomm_get_vb(dev); | ||
622 | if (!dev_priv->blit_vb) | ||
623 | return; | ||
624 | set_shaders(dev); | ||
625 | vb = r600_nomm_get_vb_ptr(dev); | ||
626 | #endif | ||
627 | } | ||
628 | |||
629 | vb[0] = i2f(dst_x); | ||
630 | vb[1] = 0; | ||
631 | vb[2] = i2f(src_x); | ||
632 | vb[3] = 0; | ||
633 | |||
634 | vb[4] = i2f(dst_x); | ||
635 | vb[5] = i2f(h); | ||
636 | vb[6] = i2f(src_x); | ||
637 | vb[7] = i2f(h); | ||
638 | |||
639 | vb[8] = i2f(dst_x + cur_size); | ||
640 | vb[9] = i2f(h); | ||
641 | vb[10] = i2f(src_x + cur_size); | ||
642 | vb[11] = i2f(h); | ||
643 | |||
644 | /* src 9 */ | ||
645 | set_tex_resource(rdev, FMT_8, | ||
646 | src_x + cur_size, h, src_x + cur_size, | ||
647 | src_gpu_addr); | ||
648 | |||
649 | /* 5 */ | ||
650 | cp_set_surface_sync(rdev, | ||
651 | PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); | ||
652 | |||
653 | /* dst 23 */ | ||
654 | set_render_target(rdev, COLOR_8, | ||
655 | dst_x + cur_size, h, | ||
656 | dst_gpu_addr); | ||
657 | |||
658 | /* scissors 12 */ | ||
659 | set_scissors(rdev, dst_x, 0, dst_x + cur_size, h); | ||
660 | |||
661 | /* 14 */ | ||
662 | vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; | ||
663 | set_vtx_resource(rdev, vb_gpu_addr); | ||
664 | |||
665 | /* draw 10 */ | ||
666 | draw_auto(rdev); | ||
667 | |||
668 | /* 5 */ | ||
669 | cp_set_surface_sync(rdev, | ||
670 | PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, | ||
671 | cur_size * h, dst_gpu_addr); | ||
672 | |||
673 | vb += 12; | ||
674 | rdev->r600_blit.vb_used += 12 * 4; | ||
675 | |||
676 | src_gpu_addr += cur_size * h; | ||
677 | dst_gpu_addr += cur_size * h; | ||
678 | size_bytes -= cur_size * h; | ||
679 | } | ||
680 | } else { | ||
681 | max_bytes = 8192 * 4; | ||
682 | |||
683 | while (size_bytes) { | ||
684 | int cur_size = size_bytes; | ||
685 | int src_x = (src_gpu_addr & 255); | ||
686 | int dst_x = (dst_gpu_addr & 255); | ||
687 | int h = 1; | ||
688 | src_gpu_addr = src_gpu_addr & ~255; | ||
689 | dst_gpu_addr = dst_gpu_addr & ~255; | ||
690 | |||
691 | if (!src_x && !dst_x) { | ||
692 | h = (cur_size / max_bytes); | ||
693 | if (h > 8192) | ||
694 | h = 8192; | ||
695 | if (h == 0) | ||
696 | h = 1; | ||
697 | else | ||
698 | cur_size = max_bytes; | ||
699 | } else { | ||
700 | if (cur_size > max_bytes) | ||
701 | cur_size = max_bytes; | ||
702 | if (cur_size > (max_bytes - dst_x)) | ||
703 | cur_size = (max_bytes - dst_x); | ||
704 | if (cur_size > (max_bytes - src_x)) | ||
705 | cur_size = (max_bytes - src_x); | ||
706 | } | ||
707 | |||
708 | if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { | ||
709 | WARN_ON(1); | ||
710 | } | ||
711 | #if 0 | ||
712 | if ((rdev->blit_vb->used + 48) > rdev->blit_vb->total) { | ||
713 | r600_nomm_put_vb(dev); | ||
714 | r600_nomm_get_vb(dev); | ||
715 | if (!rdev->blit_vb) | ||
716 | return; | ||
717 | |||
718 | set_shaders(dev); | ||
719 | vb = r600_nomm_get_vb_ptr(dev); | ||
720 | } | ||
721 | #endif | ||
722 | |||
723 | vb[0] = i2f(dst_x / 4); | ||
724 | vb[1] = 0; | ||
725 | vb[2] = i2f(src_x / 4); | ||
726 | vb[3] = 0; | ||
727 | |||
728 | vb[4] = i2f(dst_x / 4); | ||
729 | vb[5] = i2f(h); | ||
730 | vb[6] = i2f(src_x / 4); | ||
731 | vb[7] = i2f(h); | ||
732 | |||
733 | vb[8] = i2f((dst_x + cur_size) / 4); | ||
734 | vb[9] = i2f(h); | ||
735 | vb[10] = i2f((src_x + cur_size) / 4); | ||
736 | vb[11] = i2f(h); | ||
737 | |||
738 | /* src 9 */ | ||
739 | set_tex_resource(rdev, FMT_8_8_8_8, | ||
740 | (src_x + cur_size) / 4, | ||
741 | h, (src_x + cur_size) / 4, | ||
742 | src_gpu_addr); | ||
743 | /* 5 */ | ||
744 | cp_set_surface_sync(rdev, | ||
745 | PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); | ||
746 | |||
747 | /* dst 23 */ | ||
748 | set_render_target(rdev, COLOR_8_8_8_8, | ||
749 | dst_x + cur_size, h, | ||
750 | dst_gpu_addr); | ||
751 | |||
752 | /* scissors 12 */ | ||
753 | set_scissors(rdev, (dst_x / 4), 0, (dst_x + cur_size / 4), h); | ||
754 | |||
755 | /* Vertex buffer setup 14 */ | ||
756 | vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; | ||
757 | set_vtx_resource(rdev, vb_gpu_addr); | ||
758 | |||
759 | /* draw 10 */ | ||
760 | draw_auto(rdev); | ||
761 | |||
762 | /* 5 */ | ||
763 | cp_set_surface_sync(rdev, | ||
764 | PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, | ||
765 | cur_size * h, dst_gpu_addr); | ||
766 | |||
767 | /* 78 ring dwords per loop */ | ||
768 | vb += 12; | ||
769 | rdev->r600_blit.vb_used += 12 * 4; | ||
770 | |||
771 | src_gpu_addr += cur_size * h; | ||
772 | dst_gpu_addr += cur_size * h; | ||
773 | size_bytes -= cur_size * h; | ||
774 | } | ||
775 | } | ||
776 | } | ||
777 | |||
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c new file mode 100644 index 000000000000..d745e815c2e8 --- /dev/null +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c | |||
@@ -0,0 +1,1072 @@ | |||
1 | |||
2 | #include <linux/types.h> | ||
3 | #include <linux/kernel.h> | ||
4 | |||
5 | const u32 r6xx_default_state[] = | ||
6 | { | ||
7 | 0xc0002400, | ||
8 | 0x00000000, | ||
9 | 0xc0012800, | ||
10 | 0x80000000, | ||
11 | 0x80000000, | ||
12 | 0xc0004600, | ||
13 | 0x00000016, | ||
14 | 0xc0016800, | ||
15 | 0x00000010, | ||
16 | 0x00028000, | ||
17 | 0xc0016800, | ||
18 | 0x00000010, | ||
19 | 0x00008000, | ||
20 | 0xc0016800, | ||
21 | 0x00000542, | ||
22 | 0x07000003, | ||
23 | 0xc0016800, | ||
24 | 0x000005c5, | ||
25 | 0x00000000, | ||
26 | 0xc0016800, | ||
27 | 0x00000363, | ||
28 | 0x00000000, | ||
29 | 0xc0016800, | ||
30 | 0x0000060c, | ||
31 | 0x82000000, | ||
32 | 0xc0016800, | ||
33 | 0x0000060e, | ||
34 | 0x01020204, | ||
35 | 0xc0016f00, | ||
36 | 0x00000000, | ||
37 | 0x00000000, | ||
38 | 0xc0016f00, | ||
39 | 0x00000001, | ||
40 | 0x00000000, | ||
41 | 0xc0096900, | ||
42 | 0x0000022a, | ||
43 | 0x00000000, | ||
44 | 0x00000000, | ||
45 | 0x00000000, | ||
46 | 0x00000000, | ||
47 | 0x00000000, | ||
48 | 0x00000000, | ||
49 | 0x00000000, | ||
50 | 0x00000000, | ||
51 | 0x00000000, | ||
52 | 0xc0016900, | ||
53 | 0x00000004, | ||
54 | 0x00000000, | ||
55 | 0xc0016900, | ||
56 | 0x0000000a, | ||
57 | 0x00000000, | ||
58 | 0xc0016900, | ||
59 | 0x0000000b, | ||
60 | 0x00000000, | ||
61 | 0xc0016900, | ||
62 | 0x0000010c, | ||
63 | 0x00000000, | ||
64 | 0xc0016900, | ||
65 | 0x0000010d, | ||
66 | 0x00000000, | ||
67 | 0xc0016900, | ||
68 | 0x00000200, | ||
69 | 0x00000000, | ||
70 | 0xc0016900, | ||
71 | 0x00000343, | ||
72 | 0x00000060, | ||
73 | 0xc0016900, | ||
74 | 0x00000344, | ||
75 | 0x00000040, | ||
76 | 0xc0016900, | ||
77 | 0x00000351, | ||
78 | 0x0000aa00, | ||
79 | 0xc0016900, | ||
80 | 0x00000104, | ||
81 | 0x00000000, | ||
82 | 0xc0016900, | ||
83 | 0x0000010e, | ||
84 | 0x00000000, | ||
85 | 0xc0046900, | ||
86 | 0x00000105, | ||
87 | 0x00000000, | ||
88 | 0x00000000, | ||
89 | 0x00000000, | ||
90 | 0x00000000, | ||
91 | 0xc0036900, | ||
92 | 0x00000109, | ||
93 | 0x00000000, | ||
94 | 0x00000000, | ||
95 | 0x00000000, | ||
96 | 0xc0046900, | ||
97 | 0x0000030c, | ||
98 | 0x01000000, | ||
99 | 0x00000000, | ||
100 | 0x00000000, | ||
101 | 0x00000000, | ||
102 | 0xc0046900, | ||
103 | 0x00000048, | ||
104 | 0x3f800000, | ||
105 | 0x00000000, | ||
106 | 0x3f800000, | ||
107 | 0x3f800000, | ||
108 | 0xc0016900, | ||
109 | 0x0000008e, | ||
110 | 0x0000000f, | ||
111 | 0xc0016900, | ||
112 | 0x00000080, | ||
113 | 0x00000000, | ||
114 | 0xc0016900, | ||
115 | 0x00000083, | ||
116 | 0x0000ffff, | ||
117 | 0xc0016900, | ||
118 | 0x00000084, | ||
119 | 0x00000000, | ||
120 | 0xc0016900, | ||
121 | 0x00000085, | ||
122 | 0x20002000, | ||
123 | 0xc0016900, | ||
124 | 0x00000086, | ||
125 | 0x00000000, | ||
126 | 0xc0016900, | ||
127 | 0x00000087, | ||
128 | 0x20002000, | ||
129 | 0xc0016900, | ||
130 | 0x00000088, | ||
131 | 0x00000000, | ||
132 | 0xc0016900, | ||
133 | 0x00000089, | ||
134 | 0x20002000, | ||
135 | 0xc0016900, | ||
136 | 0x0000008a, | ||
137 | 0x00000000, | ||
138 | 0xc0016900, | ||
139 | 0x0000008b, | ||
140 | 0x20002000, | ||
141 | 0xc0016900, | ||
142 | 0x0000008c, | ||
143 | 0x00000000, | ||
144 | 0xc0016900, | ||
145 | 0x00000094, | ||
146 | 0x80000000, | ||
147 | 0xc0016900, | ||
148 | 0x00000095, | ||
149 | 0x20002000, | ||
150 | 0xc0026900, | ||
151 | 0x000000b4, | ||
152 | 0x00000000, | ||
153 | 0x3f800000, | ||
154 | 0xc0016900, | ||
155 | 0x00000096, | ||
156 | 0x80000000, | ||
157 | 0xc0016900, | ||
158 | 0x00000097, | ||
159 | 0x20002000, | ||
160 | 0xc0026900, | ||
161 | 0x000000b6, | ||
162 | 0x00000000, | ||
163 | 0x3f800000, | ||
164 | 0xc0016900, | ||
165 | 0x00000098, | ||
166 | 0x80000000, | ||
167 | 0xc0016900, | ||
168 | 0x00000099, | ||
169 | 0x20002000, | ||
170 | 0xc0026900, | ||
171 | 0x000000b8, | ||
172 | 0x00000000, | ||
173 | 0x3f800000, | ||
174 | 0xc0016900, | ||
175 | 0x0000009a, | ||
176 | 0x80000000, | ||
177 | 0xc0016900, | ||
178 | 0x0000009b, | ||
179 | 0x20002000, | ||
180 | 0xc0026900, | ||
181 | 0x000000ba, | ||
182 | 0x00000000, | ||
183 | 0x3f800000, | ||
184 | 0xc0016900, | ||
185 | 0x0000009c, | ||
186 | 0x80000000, | ||
187 | 0xc0016900, | ||
188 | 0x0000009d, | ||
189 | 0x20002000, | ||
190 | 0xc0026900, | ||
191 | 0x000000bc, | ||
192 | 0x00000000, | ||
193 | 0x3f800000, | ||
194 | 0xc0016900, | ||
195 | 0x0000009e, | ||
196 | 0x80000000, | ||
197 | 0xc0016900, | ||
198 | 0x0000009f, | ||
199 | 0x20002000, | ||
200 | 0xc0026900, | ||
201 | 0x000000be, | ||
202 | 0x00000000, | ||
203 | 0x3f800000, | ||
204 | 0xc0016900, | ||
205 | 0x000000a0, | ||
206 | 0x80000000, | ||
207 | 0xc0016900, | ||
208 | 0x000000a1, | ||
209 | 0x20002000, | ||
210 | 0xc0026900, | ||
211 | 0x000000c0, | ||
212 | 0x00000000, | ||
213 | 0x3f800000, | ||
214 | 0xc0016900, | ||
215 | 0x000000a2, | ||
216 | 0x80000000, | ||
217 | 0xc0016900, | ||
218 | 0x000000a3, | ||
219 | 0x20002000, | ||
220 | 0xc0026900, | ||
221 | 0x000000c2, | ||
222 | 0x00000000, | ||
223 | 0x3f800000, | ||
224 | 0xc0016900, | ||
225 | 0x000000a4, | ||
226 | 0x80000000, | ||
227 | 0xc0016900, | ||
228 | 0x000000a5, | ||
229 | 0x20002000, | ||
230 | 0xc0026900, | ||
231 | 0x000000c4, | ||
232 | 0x00000000, | ||
233 | 0x3f800000, | ||
234 | 0xc0016900, | ||
235 | 0x000000a6, | ||
236 | 0x80000000, | ||
237 | 0xc0016900, | ||
238 | 0x000000a7, | ||
239 | 0x20002000, | ||
240 | 0xc0026900, | ||
241 | 0x000000c6, | ||
242 | 0x00000000, | ||
243 | 0x3f800000, | ||
244 | 0xc0016900, | ||
245 | 0x000000a8, | ||
246 | 0x80000000, | ||
247 | 0xc0016900, | ||
248 | 0x000000a9, | ||
249 | 0x20002000, | ||
250 | 0xc0026900, | ||
251 | 0x000000c8, | ||
252 | 0x00000000, | ||
253 | 0x3f800000, | ||
254 | 0xc0016900, | ||
255 | 0x000000aa, | ||
256 | 0x80000000, | ||
257 | 0xc0016900, | ||
258 | 0x000000ab, | ||
259 | 0x20002000, | ||
260 | 0xc0026900, | ||
261 | 0x000000ca, | ||
262 | 0x00000000, | ||
263 | 0x3f800000, | ||
264 | 0xc0016900, | ||
265 | 0x000000ac, | ||
266 | 0x80000000, | ||
267 | 0xc0016900, | ||
268 | 0x000000ad, | ||
269 | 0x20002000, | ||
270 | 0xc0026900, | ||
271 | 0x000000cc, | ||
272 | 0x00000000, | ||
273 | 0x3f800000, | ||
274 | 0xc0016900, | ||
275 | 0x000000ae, | ||
276 | 0x80000000, | ||
277 | 0xc0016900, | ||
278 | 0x000000af, | ||
279 | 0x20002000, | ||
280 | 0xc0026900, | ||
281 | 0x000000ce, | ||
282 | 0x00000000, | ||
283 | 0x3f800000, | ||
284 | 0xc0016900, | ||
285 | 0x000000b0, | ||
286 | 0x80000000, | ||
287 | 0xc0016900, | ||
288 | 0x000000b1, | ||
289 | 0x20002000, | ||
290 | 0xc0026900, | ||
291 | 0x000000d0, | ||
292 | 0x00000000, | ||
293 | 0x3f800000, | ||
294 | 0xc0016900, | ||
295 | 0x000000b2, | ||
296 | 0x80000000, | ||
297 | 0xc0016900, | ||
298 | 0x000000b3, | ||
299 | 0x20002000, | ||
300 | 0xc0026900, | ||
301 | 0x000000d2, | ||
302 | 0x00000000, | ||
303 | 0x3f800000, | ||
304 | 0xc0016900, | ||
305 | 0x00000293, | ||
306 | 0x00004010, | ||
307 | 0xc0016900, | ||
308 | 0x00000300, | ||
309 | 0x00000000, | ||
310 | 0xc0016900, | ||
311 | 0x00000301, | ||
312 | 0x00000000, | ||
313 | 0xc0016900, | ||
314 | 0x00000312, | ||
315 | 0xffffffff, | ||
316 | 0xc0016900, | ||
317 | 0x00000307, | ||
318 | 0x00000000, | ||
319 | 0xc0016900, | ||
320 | 0x00000308, | ||
321 | 0x00000000, | ||
322 | 0xc0016900, | ||
323 | 0x00000283, | ||
324 | 0x00000000, | ||
325 | 0xc0016900, | ||
326 | 0x00000292, | ||
327 | 0x00000000, | ||
328 | 0xc0066900, | ||
329 | 0x0000010f, | ||
330 | 0x00000000, | ||
331 | 0x00000000, | ||
332 | 0x00000000, | ||
333 | 0x00000000, | ||
334 | 0x00000000, | ||
335 | 0x00000000, | ||
336 | 0xc0016900, | ||
337 | 0x00000206, | ||
338 | 0x00000000, | ||
339 | 0xc0016900, | ||
340 | 0x00000207, | ||
341 | 0x00000000, | ||
342 | 0xc0016900, | ||
343 | 0x00000208, | ||
344 | 0x00000000, | ||
345 | 0xc0046900, | ||
346 | 0x00000303, | ||
347 | 0x3f800000, | ||
348 | 0x3f800000, | ||
349 | 0x3f800000, | ||
350 | 0x3f800000, | ||
351 | 0xc0016900, | ||
352 | 0x00000205, | ||
353 | 0x00000004, | ||
354 | 0xc0016900, | ||
355 | 0x00000280, | ||
356 | 0x00000000, | ||
357 | 0xc0016900, | ||
358 | 0x00000281, | ||
359 | 0x00000000, | ||
360 | 0xc0016900, | ||
361 | 0x0000037e, | ||
362 | 0x00000000, | ||
363 | 0xc0016900, | ||
364 | 0x00000382, | ||
365 | 0x00000000, | ||
366 | 0xc0016900, | ||
367 | 0x00000380, | ||
368 | 0x00000000, | ||
369 | 0xc0016900, | ||
370 | 0x00000383, | ||
371 | 0x00000000, | ||
372 | 0xc0016900, | ||
373 | 0x00000381, | ||
374 | 0x00000000, | ||
375 | 0xc0016900, | ||
376 | 0x00000282, | ||
377 | 0x00000008, | ||
378 | 0xc0016900, | ||
379 | 0x00000302, | ||
380 | 0x0000002d, | ||
381 | 0xc0016900, | ||
382 | 0x0000037f, | ||
383 | 0x00000000, | ||
384 | 0xc0016900, | ||
385 | 0x000001b2, | ||
386 | 0x00000000, | ||
387 | 0xc0016900, | ||
388 | 0x000001b6, | ||
389 | 0x00000000, | ||
390 | 0xc0016900, | ||
391 | 0x000001b7, | ||
392 | 0x00000000, | ||
393 | 0xc0016900, | ||
394 | 0x000001b8, | ||
395 | 0x00000000, | ||
396 | 0xc0016900, | ||
397 | 0x000001b9, | ||
398 | 0x00000000, | ||
399 | 0xc0016900, | ||
400 | 0x00000225, | ||
401 | 0x00000000, | ||
402 | 0xc0016900, | ||
403 | 0x00000229, | ||
404 | 0x00000000, | ||
405 | 0xc0016900, | ||
406 | 0x00000237, | ||
407 | 0x00000000, | ||
408 | 0xc0016900, | ||
409 | 0x00000100, | ||
410 | 0x00000800, | ||
411 | 0xc0016900, | ||
412 | 0x00000101, | ||
413 | 0x00000000, | ||
414 | 0xc0016900, | ||
415 | 0x00000102, | ||
416 | 0x00000000, | ||
417 | 0xc0016900, | ||
418 | 0x000002a8, | ||
419 | 0x00000000, | ||
420 | 0xc0016900, | ||
421 | 0x000002a9, | ||
422 | 0x00000000, | ||
423 | 0xc0016900, | ||
424 | 0x00000103, | ||
425 | 0x00000000, | ||
426 | 0xc0016900, | ||
427 | 0x00000284, | ||
428 | 0x00000000, | ||
429 | 0xc0016900, | ||
430 | 0x00000290, | ||
431 | 0x00000000, | ||
432 | 0xc0016900, | ||
433 | 0x00000285, | ||
434 | 0x00000000, | ||
435 | 0xc0016900, | ||
436 | 0x00000286, | ||
437 | 0x00000000, | ||
438 | 0xc0016900, | ||
439 | 0x00000287, | ||
440 | 0x00000000, | ||
441 | 0xc0016900, | ||
442 | 0x00000288, | ||
443 | 0x00000000, | ||
444 | 0xc0016900, | ||
445 | 0x00000289, | ||
446 | 0x00000000, | ||
447 | 0xc0016900, | ||
448 | 0x0000028a, | ||
449 | 0x00000000, | ||
450 | 0xc0016900, | ||
451 | 0x0000028b, | ||
452 | 0x00000000, | ||
453 | 0xc0016900, | ||
454 | 0x0000028c, | ||
455 | 0x00000000, | ||
456 | 0xc0016900, | ||
457 | 0x0000028d, | ||
458 | 0x00000000, | ||
459 | 0xc0016900, | ||
460 | 0x0000028e, | ||
461 | 0x00000000, | ||
462 | 0xc0016900, | ||
463 | 0x0000028f, | ||
464 | 0x00000000, | ||
465 | 0xc0016900, | ||
466 | 0x000002a1, | ||
467 | 0x00000000, | ||
468 | 0xc0016900, | ||
469 | 0x000002a5, | ||
470 | 0x00000000, | ||
471 | 0xc0016900, | ||
472 | 0x000002ac, | ||
473 | 0x00000000, | ||
474 | 0xc0016900, | ||
475 | 0x000002ad, | ||
476 | 0x00000000, | ||
477 | 0xc0016900, | ||
478 | 0x000002ae, | ||
479 | 0x00000000, | ||
480 | 0xc0016900, | ||
481 | 0x000002c8, | ||
482 | 0x00000000, | ||
483 | 0xc0016900, | ||
484 | 0x00000206, | ||
485 | 0x00000100, | ||
486 | 0xc0016900, | ||
487 | 0x00000204, | ||
488 | 0x00010000, | ||
489 | 0xc0036e00, | ||
490 | 0x00000000, | ||
491 | 0x00000012, | ||
492 | 0x00000000, | ||
493 | 0x00000000, | ||
494 | 0xc0016900, | ||
495 | 0x0000008f, | ||
496 | 0x0000000f, | ||
497 | 0xc0016900, | ||
498 | 0x000001e8, | ||
499 | 0x00000001, | ||
500 | 0xc0016900, | ||
501 | 0x00000202, | ||
502 | 0x00cc0000, | ||
503 | 0xc0016900, | ||
504 | 0x00000205, | ||
505 | 0x00000244, | ||
506 | 0xc0016900, | ||
507 | 0x00000203, | ||
508 | 0x00000210, | ||
509 | 0xc0016900, | ||
510 | 0x000001b1, | ||
511 | 0x00000000, | ||
512 | 0xc0016900, | ||
513 | 0x00000185, | ||
514 | 0x00000000, | ||
515 | 0xc0016900, | ||
516 | 0x000001b3, | ||
517 | 0x00000001, | ||
518 | 0xc0016900, | ||
519 | 0x000001b4, | ||
520 | 0x00000000, | ||
521 | 0xc0016900, | ||
522 | 0x00000191, | ||
523 | 0x00000b00, | ||
524 | 0xc0016900, | ||
525 | 0x000001b5, | ||
526 | 0x00000000, | ||
527 | }; | ||
528 | |||
529 | const u32 r7xx_default_state[] = | ||
530 | { | ||
531 | 0xc0012800, | ||
532 | 0x80000000, | ||
533 | 0x80000000, | ||
534 | 0xc0004600, | ||
535 | 0x00000016, | ||
536 | 0xc0016800, | ||
537 | 0x00000010, | ||
538 | 0x00028000, | ||
539 | 0xc0016800, | ||
540 | 0x00000010, | ||
541 | 0x00008000, | ||
542 | 0xc0016800, | ||
543 | 0x00000542, | ||
544 | 0x07000002, | ||
545 | 0xc0016800, | ||
546 | 0x000005c5, | ||
547 | 0x00000000, | ||
548 | 0xc0016800, | ||
549 | 0x00000363, | ||
550 | 0x00004000, | ||
551 | 0xc0016800, | ||
552 | 0x0000060c, | ||
553 | 0x00000000, | ||
554 | 0xc0016800, | ||
555 | 0x0000060e, | ||
556 | 0x00420204, | ||
557 | 0xc0016f00, | ||
558 | 0x00000000, | ||
559 | 0x00000000, | ||
560 | 0xc0016f00, | ||
561 | 0x00000001, | ||
562 | 0x00000000, | ||
563 | 0xc0096900, | ||
564 | 0x0000022a, | ||
565 | 0x00000000, | ||
566 | 0x00000000, | ||
567 | 0x00000000, | ||
568 | 0x00000000, | ||
569 | 0x00000000, | ||
570 | 0x00000000, | ||
571 | 0x00000000, | ||
572 | 0x00000000, | ||
573 | 0x00000000, | ||
574 | 0xc0016900, | ||
575 | 0x00000004, | ||
576 | 0x00000000, | ||
577 | 0xc0016900, | ||
578 | 0x0000000a, | ||
579 | 0x00000000, | ||
580 | 0xc0016900, | ||
581 | 0x0000000b, | ||
582 | 0x00000000, | ||
583 | 0xc0016900, | ||
584 | 0x0000010c, | ||
585 | 0x00000000, | ||
586 | 0xc0016900, | ||
587 | 0x0000010d, | ||
588 | 0x00000000, | ||
589 | 0xc0016900, | ||
590 | 0x00000200, | ||
591 | 0x00000000, | ||
592 | 0xc0016900, | ||
593 | 0x00000343, | ||
594 | 0x00000060, | ||
595 | 0xc0016900, | ||
596 | 0x00000344, | ||
597 | 0x00000000, | ||
598 | 0xc0016900, | ||
599 | 0x00000351, | ||
600 | 0x0000aa00, | ||
601 | 0xc0016900, | ||
602 | 0x00000104, | ||
603 | 0x00000000, | ||
604 | 0xc0016900, | ||
605 | 0x0000010e, | ||
606 | 0x00000000, | ||
607 | 0xc0046900, | ||
608 | 0x00000105, | ||
609 | 0x00000000, | ||
610 | 0x00000000, | ||
611 | 0x00000000, | ||
612 | 0x00000000, | ||
613 | 0xc0046900, | ||
614 | 0x0000030c, | ||
615 | 0x01000000, | ||
616 | 0x00000000, | ||
617 | 0x00000000, | ||
618 | 0x00000000, | ||
619 | 0xc0016900, | ||
620 | 0x0000008e, | ||
621 | 0x0000000f, | ||
622 | 0xc0016900, | ||
623 | 0x00000080, | ||
624 | 0x00000000, | ||
625 | 0xc0016900, | ||
626 | 0x00000083, | ||
627 | 0x0000ffff, | ||
628 | 0xc0016900, | ||
629 | 0x00000084, | ||
630 | 0x00000000, | ||
631 | 0xc0016900, | ||
632 | 0x00000085, | ||
633 | 0x20002000, | ||
634 | 0xc0016900, | ||
635 | 0x00000086, | ||
636 | 0x00000000, | ||
637 | 0xc0016900, | ||
638 | 0x00000087, | ||
639 | 0x20002000, | ||
640 | 0xc0016900, | ||
641 | 0x00000088, | ||
642 | 0x00000000, | ||
643 | 0xc0016900, | ||
644 | 0x00000089, | ||
645 | 0x20002000, | ||
646 | 0xc0016900, | ||
647 | 0x0000008a, | ||
648 | 0x00000000, | ||
649 | 0xc0016900, | ||
650 | 0x0000008b, | ||
651 | 0x20002000, | ||
652 | 0xc0016900, | ||
653 | 0x0000008c, | ||
654 | 0xaaaaaaaa, | ||
655 | 0xc0016900, | ||
656 | 0x00000094, | ||
657 | 0x80000000, | ||
658 | 0xc0016900, | ||
659 | 0x00000095, | ||
660 | 0x20002000, | ||
661 | 0xc0026900, | ||
662 | 0x000000b4, | ||
663 | 0x00000000, | ||
664 | 0x3f800000, | ||
665 | 0xc0016900, | ||
666 | 0x00000096, | ||
667 | 0x80000000, | ||
668 | 0xc0016900, | ||
669 | 0x00000097, | ||
670 | 0x20002000, | ||
671 | 0xc0026900, | ||
672 | 0x000000b6, | ||
673 | 0x00000000, | ||
674 | 0x3f800000, | ||
675 | 0xc0016900, | ||
676 | 0x00000098, | ||
677 | 0x80000000, | ||
678 | 0xc0016900, | ||
679 | 0x00000099, | ||
680 | 0x20002000, | ||
681 | 0xc0026900, | ||
682 | 0x000000b8, | ||
683 | 0x00000000, | ||
684 | 0x3f800000, | ||
685 | 0xc0016900, | ||
686 | 0x0000009a, | ||
687 | 0x80000000, | ||
688 | 0xc0016900, | ||
689 | 0x0000009b, | ||
690 | 0x20002000, | ||
691 | 0xc0026900, | ||
692 | 0x000000ba, | ||
693 | 0x00000000, | ||
694 | 0x3f800000, | ||
695 | 0xc0016900, | ||
696 | 0x0000009c, | ||
697 | 0x80000000, | ||
698 | 0xc0016900, | ||
699 | 0x0000009d, | ||
700 | 0x20002000, | ||
701 | 0xc0026900, | ||
702 | 0x000000bc, | ||
703 | 0x00000000, | ||
704 | 0x3f800000, | ||
705 | 0xc0016900, | ||
706 | 0x0000009e, | ||
707 | 0x80000000, | ||
708 | 0xc0016900, | ||
709 | 0x0000009f, | ||
710 | 0x20002000, | ||
711 | 0xc0026900, | ||
712 | 0x000000be, | ||
713 | 0x00000000, | ||
714 | 0x3f800000, | ||
715 | 0xc0016900, | ||
716 | 0x000000a0, | ||
717 | 0x80000000, | ||
718 | 0xc0016900, | ||
719 | 0x000000a1, | ||
720 | 0x20002000, | ||
721 | 0xc0026900, | ||
722 | 0x000000c0, | ||
723 | 0x00000000, | ||
724 | 0x3f800000, | ||
725 | 0xc0016900, | ||
726 | 0x000000a2, | ||
727 | 0x80000000, | ||
728 | 0xc0016900, | ||
729 | 0x000000a3, | ||
730 | 0x20002000, | ||
731 | 0xc0026900, | ||
732 | 0x000000c2, | ||
733 | 0x00000000, | ||
734 | 0x3f800000, | ||
735 | 0xc0016900, | ||
736 | 0x000000a4, | ||
737 | 0x80000000, | ||
738 | 0xc0016900, | ||
739 | 0x000000a5, | ||
740 | 0x20002000, | ||
741 | 0xc0026900, | ||
742 | 0x000000c4, | ||
743 | 0x00000000, | ||
744 | 0x3f800000, | ||
745 | 0xc0016900, | ||
746 | 0x000000a6, | ||
747 | 0x80000000, | ||
748 | 0xc0016900, | ||
749 | 0x000000a7, | ||
750 | 0x20002000, | ||
751 | 0xc0026900, | ||
752 | 0x000000c6, | ||
753 | 0x00000000, | ||
754 | 0x3f800000, | ||
755 | 0xc0016900, | ||
756 | 0x000000a8, | ||
757 | 0x80000000, | ||
758 | 0xc0016900, | ||
759 | 0x000000a9, | ||
760 | 0x20002000, | ||
761 | 0xc0026900, | ||
762 | 0x000000c8, | ||
763 | 0x00000000, | ||
764 | 0x3f800000, | ||
765 | 0xc0016900, | ||
766 | 0x000000aa, | ||
767 | 0x80000000, | ||
768 | 0xc0016900, | ||
769 | 0x000000ab, | ||
770 | 0x20002000, | ||
771 | 0xc0026900, | ||
772 | 0x000000ca, | ||
773 | 0x00000000, | ||
774 | 0x3f800000, | ||
775 | 0xc0016900, | ||
776 | 0x000000ac, | ||
777 | 0x80000000, | ||
778 | 0xc0016900, | ||
779 | 0x000000ad, | ||
780 | 0x20002000, | ||
781 | 0xc0026900, | ||
782 | 0x000000cc, | ||
783 | 0x00000000, | ||
784 | 0x3f800000, | ||
785 | 0xc0016900, | ||
786 | 0x000000ae, | ||
787 | 0x80000000, | ||
788 | 0xc0016900, | ||
789 | 0x000000af, | ||
790 | 0x20002000, | ||
791 | 0xc0026900, | ||
792 | 0x000000ce, | ||
793 | 0x00000000, | ||
794 | 0x3f800000, | ||
795 | 0xc0016900, | ||
796 | 0x000000b0, | ||
797 | 0x80000000, | ||
798 | 0xc0016900, | ||
799 | 0x000000b1, | ||
800 | 0x20002000, | ||
801 | 0xc0026900, | ||
802 | 0x000000d0, | ||
803 | 0x00000000, | ||
804 | 0x3f800000, | ||
805 | 0xc0016900, | ||
806 | 0x000000b2, | ||
807 | 0x80000000, | ||
808 | 0xc0016900, | ||
809 | 0x000000b3, | ||
810 | 0x20002000, | ||
811 | 0xc0026900, | ||
812 | 0x000000d2, | ||
813 | 0x00000000, | ||
814 | 0x3f800000, | ||
815 | 0xc0016900, | ||
816 | 0x00000293, | ||
817 | 0x00514000, | ||
818 | 0xc0016900, | ||
819 | 0x00000300, | ||
820 | 0x00000000, | ||
821 | 0xc0016900, | ||
822 | 0x00000301, | ||
823 | 0x00000000, | ||
824 | 0xc0016900, | ||
825 | 0x00000312, | ||
826 | 0xffffffff, | ||
827 | 0xc0016900, | ||
828 | 0x00000307, | ||
829 | 0x00000000, | ||
830 | 0xc0016900, | ||
831 | 0x00000308, | ||
832 | 0x00000000, | ||
833 | 0xc0016900, | ||
834 | 0x00000283, | ||
835 | 0x00000000, | ||
836 | 0xc0016900, | ||
837 | 0x00000292, | ||
838 | 0x00000000, | ||
839 | 0xc0066900, | ||
840 | 0x0000010f, | ||
841 | 0x00000000, | ||
842 | 0x00000000, | ||
843 | 0x00000000, | ||
844 | 0x00000000, | ||
845 | 0x00000000, | ||
846 | 0x00000000, | ||
847 | 0xc0016900, | ||
848 | 0x00000206, | ||
849 | 0x00000000, | ||
850 | 0xc0016900, | ||
851 | 0x00000207, | ||
852 | 0x00000000, | ||
853 | 0xc0016900, | ||
854 | 0x00000208, | ||
855 | 0x00000000, | ||
856 | 0xc0046900, | ||
857 | 0x00000303, | ||
858 | 0x3f800000, | ||
859 | 0x3f800000, | ||
860 | 0x3f800000, | ||
861 | 0x3f800000, | ||
862 | 0xc0016900, | ||
863 | 0x00000205, | ||
864 | 0x00000004, | ||
865 | 0xc0016900, | ||
866 | 0x00000280, | ||
867 | 0x00000000, | ||
868 | 0xc0016900, | ||
869 | 0x00000281, | ||
870 | 0x00000000, | ||
871 | 0xc0016900, | ||
872 | 0x0000037e, | ||
873 | 0x00000000, | ||
874 | 0xc0016900, | ||
875 | 0x00000382, | ||
876 | 0x00000000, | ||
877 | 0xc0016900, | ||
878 | 0x00000380, | ||
879 | 0x00000000, | ||
880 | 0xc0016900, | ||
881 | 0x00000383, | ||
882 | 0x00000000, | ||
883 | 0xc0016900, | ||
884 | 0x00000381, | ||
885 | 0x00000000, | ||
886 | 0xc0016900, | ||
887 | 0x00000282, | ||
888 | 0x00000008, | ||
889 | 0xc0016900, | ||
890 | 0x00000302, | ||
891 | 0x0000002d, | ||
892 | 0xc0016900, | ||
893 | 0x0000037f, | ||
894 | 0x00000000, | ||
895 | 0xc0016900, | ||
896 | 0x000001b2, | ||
897 | 0x00000001, | ||
898 | 0xc0016900, | ||
899 | 0x000001b6, | ||
900 | 0x00000000, | ||
901 | 0xc0016900, | ||
902 | 0x000001b7, | ||
903 | 0x00000000, | ||
904 | 0xc0016900, | ||
905 | 0x000001b8, | ||
906 | 0x00000000, | ||
907 | 0xc0016900, | ||
908 | 0x000001b9, | ||
909 | 0x00000000, | ||
910 | 0xc0016900, | ||
911 | 0x00000225, | ||
912 | 0x00000000, | ||
913 | 0xc0016900, | ||
914 | 0x00000229, | ||
915 | 0x00000000, | ||
916 | 0xc0016900, | ||
917 | 0x00000237, | ||
918 | 0x00000000, | ||
919 | 0xc0016900, | ||
920 | 0x00000100, | ||
921 | 0x00000800, | ||
922 | 0xc0016900, | ||
923 | 0x00000101, | ||
924 | 0x00000000, | ||
925 | 0xc0016900, | ||
926 | 0x00000102, | ||
927 | 0x00000000, | ||
928 | 0xc0016900, | ||
929 | 0x000002a8, | ||
930 | 0x00000000, | ||
931 | 0xc0016900, | ||
932 | 0x000002a9, | ||
933 | 0x00000000, | ||
934 | 0xc0016900, | ||
935 | 0x00000103, | ||
936 | 0x00000000, | ||
937 | 0xc0016900, | ||
938 | 0x00000284, | ||
939 | 0x00000000, | ||
940 | 0xc0016900, | ||
941 | 0x00000290, | ||
942 | 0x00000000, | ||
943 | 0xc0016900, | ||
944 | 0x00000285, | ||
945 | 0x00000000, | ||
946 | 0xc0016900, | ||
947 | 0x00000286, | ||
948 | 0x00000000, | ||
949 | 0xc0016900, | ||
950 | 0x00000287, | ||
951 | 0x00000000, | ||
952 | 0xc0016900, | ||
953 | 0x00000288, | ||
954 | 0x00000000, | ||
955 | 0xc0016900, | ||
956 | 0x00000289, | ||
957 | 0x00000000, | ||
958 | 0xc0016900, | ||
959 | 0x0000028a, | ||
960 | 0x00000000, | ||
961 | 0xc0016900, | ||
962 | 0x0000028b, | ||
963 | 0x00000000, | ||
964 | 0xc0016900, | ||
965 | 0x0000028c, | ||
966 | 0x00000000, | ||
967 | 0xc0016900, | ||
968 | 0x0000028d, | ||
969 | 0x00000000, | ||
970 | 0xc0016900, | ||
971 | 0x0000028e, | ||
972 | 0x00000000, | ||
973 | 0xc0016900, | ||
974 | 0x0000028f, | ||
975 | 0x00000000, | ||
976 | 0xc0016900, | ||
977 | 0x000002a1, | ||
978 | 0x00000000, | ||
979 | 0xc0016900, | ||
980 | 0x000002a5, | ||
981 | 0x00000000, | ||
982 | 0xc0016900, | ||
983 | 0x000002ac, | ||
984 | 0x00000000, | ||
985 | 0xc0016900, | ||
986 | 0x000002ad, | ||
987 | 0x00000000, | ||
988 | 0xc0016900, | ||
989 | 0x000002ae, | ||
990 | 0x00000000, | ||
991 | 0xc0016900, | ||
992 | 0x000002c8, | ||
993 | 0x00000000, | ||
994 | 0xc0016900, | ||
995 | 0x00000206, | ||
996 | 0x00000100, | ||
997 | 0xc0016900, | ||
998 | 0x00000204, | ||
999 | 0x00010000, | ||
1000 | 0xc0036e00, | ||
1001 | 0x00000000, | ||
1002 | 0x00000012, | ||
1003 | 0x00000000, | ||
1004 | 0x00000000, | ||
1005 | 0xc0016900, | ||
1006 | 0x0000008f, | ||
1007 | 0x0000000f, | ||
1008 | 0xc0016900, | ||
1009 | 0x000001e8, | ||
1010 | 0x00000001, | ||
1011 | 0xc0016900, | ||
1012 | 0x00000202, | ||
1013 | 0x00cc0000, | ||
1014 | 0xc0016900, | ||
1015 | 0x00000205, | ||
1016 | 0x00000244, | ||
1017 | 0xc0016900, | ||
1018 | 0x00000203, | ||
1019 | 0x00000210, | ||
1020 | 0xc0016900, | ||
1021 | 0x000001b1, | ||
1022 | 0x00000000, | ||
1023 | 0xc0016900, | ||
1024 | 0x00000185, | ||
1025 | 0x00000000, | ||
1026 | 0xc0016900, | ||
1027 | 0x000001b3, | ||
1028 | 0x00000001, | ||
1029 | 0xc0016900, | ||
1030 | 0x000001b4, | ||
1031 | 0x00000000, | ||
1032 | 0xc0016900, | ||
1033 | 0x00000191, | ||
1034 | 0x00000b00, | ||
1035 | 0xc0016900, | ||
1036 | 0x000001b5, | ||
1037 | 0x00000000, | ||
1038 | }; | ||
1039 | |||
1040 | /* same for r6xx/r7xx */ | ||
1041 | const u32 r6xx_vs[] = | ||
1042 | { | ||
1043 | 0x00000004, | ||
1044 | 0x81000000, | ||
1045 | 0x0000203c, | ||
1046 | 0x94000b08, | ||
1047 | 0x00004000, | ||
1048 | 0x14200b1a, | ||
1049 | 0x00000000, | ||
1050 | 0x00000000, | ||
1051 | 0x3c000000, | ||
1052 | 0x68cd1000, | ||
1053 | 0x00080000, | ||
1054 | 0x00000000, | ||
1055 | }; | ||
1056 | |||
1057 | const u32 r6xx_ps[] = | ||
1058 | { | ||
1059 | 0x00000002, | ||
1060 | 0x80800000, | ||
1061 | 0x00000000, | ||
1062 | 0x94200688, | ||
1063 | 0x00000010, | ||
1064 | 0x000d1000, | ||
1065 | 0xb0800000, | ||
1066 | 0x00000000, | ||
1067 | }; | ||
1068 | |||
1069 | const u32 r6xx_ps_size = ARRAY_SIZE(r6xx_ps); | ||
1070 | const u32 r6xx_vs_size = ARRAY_SIZE(r6xx_vs); | ||
1071 | const u32 r6xx_default_size = ARRAY_SIZE(r6xx_default_state); | ||
1072 | const u32 r7xx_default_size = ARRAY_SIZE(r7xx_default_state); | ||
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h new file mode 100644 index 000000000000..fdc3b378cbb0 --- /dev/null +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h | |||
@@ -0,0 +1,14 @@ | |||
1 | |||
2 | #ifndef R600_BLIT_SHADERS_H | ||
3 | #define R600_BLIT_SHADERS_H | ||
4 | |||
5 | extern const u32 r6xx_ps[]; | ||
6 | extern const u32 r6xx_vs[]; | ||
7 | extern const u32 r7xx_default_state[]; | ||
8 | extern const u32 r6xx_default_state[]; | ||
9 | |||
10 | |||
11 | extern const u32 r6xx_ps_size, r6xx_vs_size; | ||
12 | extern const u32 r6xx_default_size, r7xx_default_size; | ||
13 | |||
14 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 8327912de964..6d5a711c2e91 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
@@ -58,6 +58,12 @@ MODULE_FIRMWARE("radeon/RV730_me.bin"); | |||
58 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); | 58 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); |
59 | MODULE_FIRMWARE("radeon/RV710_me.bin"); | 59 | MODULE_FIRMWARE("radeon/RV710_me.bin"); |
60 | 60 | ||
61 | |||
62 | int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, | ||
63 | unsigned family, u32 *ib, int *l); | ||
64 | void r600_cs_legacy_init(void); | ||
65 | |||
66 | |||
61 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ | 67 | # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ |
62 | # define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) | 68 | # define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) |
63 | 69 | ||
@@ -1857,6 +1863,8 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | |||
1857 | 1863 | ||
1858 | DRM_DEBUG("\n"); | 1864 | DRM_DEBUG("\n"); |
1859 | 1865 | ||
1866 | mutex_init(&dev_priv->cs_mutex); | ||
1867 | r600_cs_legacy_init(); | ||
1860 | /* if we require new memory map but we don't have it fail */ | 1868 | /* if we require new memory map but we don't have it fail */ |
1861 | if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { | 1869 | if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { |
1862 | DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); | 1870 | DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); |
@@ -1888,7 +1896,7 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | |||
1888 | /* Enable vblank on CRTC1 for older X servers | 1896 | /* Enable vblank on CRTC1 for older X servers |
1889 | */ | 1897 | */ |
1890 | dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; | 1898 | dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; |
1891 | 1899 | dev_priv->do_boxes = 0; | |
1892 | dev_priv->cp_mode = init->cp_mode; | 1900 | dev_priv->cp_mode = init->cp_mode; |
1893 | 1901 | ||
1894 | /* We don't support anything other than bus-mastering ring mode, | 1902 | /* We don't support anything other than bus-mastering ring mode, |
@@ -1974,11 +1982,11 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | |||
1974 | } else | 1982 | } else |
1975 | #endif | 1983 | #endif |
1976 | { | 1984 | { |
1977 | dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; | 1985 | dev_priv->cp_ring->handle = (void *)(unsigned long)dev_priv->cp_ring->offset; |
1978 | dev_priv->ring_rptr->handle = | 1986 | dev_priv->ring_rptr->handle = |
1979 | (void *)dev_priv->ring_rptr->offset; | 1987 | (void *)(unsigned long)dev_priv->ring_rptr->offset; |
1980 | dev->agp_buffer_map->handle = | 1988 | dev->agp_buffer_map->handle = |
1981 | (void *)dev->agp_buffer_map->offset; | 1989 | (void *)(unsigned long)dev->agp_buffer_map->offset; |
1982 | 1990 | ||
1983 | DRM_DEBUG("dev_priv->cp_ring->handle %p\n", | 1991 | DRM_DEBUG("dev_priv->cp_ring->handle %p\n", |
1984 | dev_priv->cp_ring->handle); | 1992 | dev_priv->cp_ring->handle); |
@@ -2282,3 +2290,239 @@ int r600_cp_dispatch_indirect(struct drm_device *dev, | |||
2282 | 2290 | ||
2283 | return 0; | 2291 | return 0; |
2284 | } | 2292 | } |
2293 | |||
2294 | void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv) | ||
2295 | { | ||
2296 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
2297 | struct drm_master *master = file_priv->master; | ||
2298 | struct drm_radeon_master_private *master_priv = master->driver_priv; | ||
2299 | drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; | ||
2300 | int nbox = sarea_priv->nbox; | ||
2301 | struct drm_clip_rect *pbox = sarea_priv->boxes; | ||
2302 | int i, cpp, src_pitch, dst_pitch; | ||
2303 | uint64_t src, dst; | ||
2304 | RING_LOCALS; | ||
2305 | DRM_DEBUG("\n"); | ||
2306 | |||
2307 | if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888) | ||
2308 | cpp = 4; | ||
2309 | else | ||
2310 | cpp = 2; | ||
2311 | |||
2312 | if (sarea_priv->pfCurrentPage == 0) { | ||
2313 | src_pitch = dev_priv->back_pitch; | ||
2314 | dst_pitch = dev_priv->front_pitch; | ||
2315 | src = dev_priv->back_offset + dev_priv->fb_location; | ||
2316 | dst = dev_priv->front_offset + dev_priv->fb_location; | ||
2317 | } else { | ||
2318 | src_pitch = dev_priv->front_pitch; | ||
2319 | dst_pitch = dev_priv->back_pitch; | ||
2320 | src = dev_priv->front_offset + dev_priv->fb_location; | ||
2321 | dst = dev_priv->back_offset + dev_priv->fb_location; | ||
2322 | } | ||
2323 | |||
2324 | if (r600_prepare_blit_copy(dev, file_priv)) { | ||
2325 | DRM_ERROR("unable to allocate vertex buffer for swap buffer\n"); | ||
2326 | return; | ||
2327 | } | ||
2328 | for (i = 0; i < nbox; i++) { | ||
2329 | int x = pbox[i].x1; | ||
2330 | int y = pbox[i].y1; | ||
2331 | int w = pbox[i].x2 - x; | ||
2332 | int h = pbox[i].y2 - y; | ||
2333 | |||
2334 | DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h); | ||
2335 | |||
2336 | r600_blit_swap(dev, | ||
2337 | src, dst, | ||
2338 | x, y, x, y, w, h, | ||
2339 | src_pitch, dst_pitch, cpp); | ||
2340 | } | ||
2341 | r600_done_blit_copy(dev); | ||
2342 | |||
2343 | /* Increment the frame counter. The client-side 3D driver must | ||
2344 | * throttle the framerate by waiting for this value before | ||
2345 | * performing the swapbuffer ioctl. | ||
2346 | */ | ||
2347 | sarea_priv->last_frame++; | ||
2348 | |||
2349 | BEGIN_RING(3); | ||
2350 | R600_FRAME_AGE(sarea_priv->last_frame); | ||
2351 | ADVANCE_RING(); | ||
2352 | } | ||
2353 | |||
2354 | int r600_cp_dispatch_texture(struct drm_device *dev, | ||
2355 | struct drm_file *file_priv, | ||
2356 | drm_radeon_texture_t *tex, | ||
2357 | drm_radeon_tex_image_t *image) | ||
2358 | { | ||
2359 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
2360 | struct drm_buf *buf; | ||
2361 | u32 *buffer; | ||
2362 | const u8 __user *data; | ||
2363 | int size, pass_size; | ||
2364 | u64 src_offset, dst_offset; | ||
2365 | |||
2366 | if (!radeon_check_offset(dev_priv, tex->offset)) { | ||
2367 | DRM_ERROR("Invalid destination offset\n"); | ||
2368 | return -EINVAL; | ||
2369 | } | ||
2370 | |||
2371 | /* this might fail for zero-sized uploads - are those illegal? */ | ||
2372 | if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) { | ||
2373 | DRM_ERROR("Invalid final destination offset\n"); | ||
2374 | return -EINVAL; | ||
2375 | } | ||
2376 | |||
2377 | size = tex->height * tex->pitch; | ||
2378 | |||
2379 | if (size == 0) | ||
2380 | return 0; | ||
2381 | |||
2382 | dst_offset = tex->offset; | ||
2383 | |||
2384 | if (r600_prepare_blit_copy(dev, file_priv)) { | ||
2385 | DRM_ERROR("unable to allocate vertex buffer for swap buffer\n"); | ||
2386 | return -EAGAIN; | ||
2387 | } | ||
2388 | do { | ||
2389 | data = (const u8 __user *)image->data; | ||
2390 | pass_size = size; | ||
2391 | |||
2392 | buf = radeon_freelist_get(dev); | ||
2393 | if (!buf) { | ||
2394 | DRM_DEBUG("EAGAIN\n"); | ||
2395 | if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) | ||
2396 | return -EFAULT; | ||
2397 | return -EAGAIN; | ||
2398 | } | ||
2399 | |||
2400 | if (pass_size > buf->total) | ||
2401 | pass_size = buf->total; | ||
2402 | |||
2403 | /* Dispatch the indirect buffer. | ||
2404 | */ | ||
2405 | buffer = | ||
2406 | (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); | ||
2407 | |||
2408 | if (DRM_COPY_FROM_USER(buffer, data, pass_size)) { | ||
2409 | DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size); | ||
2410 | return -EFAULT; | ||
2411 | } | ||
2412 | |||
2413 | buf->file_priv = file_priv; | ||
2414 | buf->used = pass_size; | ||
2415 | src_offset = dev_priv->gart_buffers_offset + buf->offset; | ||
2416 | |||
2417 | r600_blit_copy(dev, src_offset, dst_offset, pass_size); | ||
2418 | |||
2419 | radeon_cp_discard_buffer(dev, file_priv->master, buf); | ||
2420 | |||
2421 | /* Update the input parameters for next time */ | ||
2422 | image->data = (const u8 __user *)image->data + pass_size; | ||
2423 | dst_offset += pass_size; | ||
2424 | size -= pass_size; | ||
2425 | } while (size > 0); | ||
2426 | r600_done_blit_copy(dev); | ||
2427 | |||
2428 | return 0; | ||
2429 | } | ||
2430 | |||
2431 | /* | ||
2432 | * Legacy cs ioctl | ||
2433 | */ | ||
2434 | static u32 radeon_cs_id_get(struct drm_radeon_private *radeon) | ||
2435 | { | ||
2436 | /* FIXME: check if wrap affect last reported wrap & sequence */ | ||
2437 | radeon->cs_id_scnt = (radeon->cs_id_scnt + 1) & 0x00FFFFFF; | ||
2438 | if (!radeon->cs_id_scnt) { | ||
2439 | /* increment wrap counter */ | ||
2440 | radeon->cs_id_wcnt += 0x01000000; | ||
2441 | /* valid sequence counter start at 1 */ | ||
2442 | radeon->cs_id_scnt = 1; | ||
2443 | } | ||
2444 | return (radeon->cs_id_scnt | radeon->cs_id_wcnt); | ||
2445 | } | ||
2446 | |||
2447 | static void r600_cs_id_emit(drm_radeon_private_t *dev_priv, u32 *id) | ||
2448 | { | ||
2449 | RING_LOCALS; | ||
2450 | |||
2451 | *id = radeon_cs_id_get(dev_priv); | ||
2452 | |||
2453 | /* SCRATCH 2 */ | ||
2454 | BEGIN_RING(3); | ||
2455 | R600_CLEAR_AGE(*id); | ||
2456 | ADVANCE_RING(); | ||
2457 | COMMIT_RING(); | ||
2458 | } | ||
2459 | |||
2460 | static int r600_ib_get(struct drm_device *dev, | ||
2461 | struct drm_file *fpriv, | ||
2462 | struct drm_buf **buffer) | ||
2463 | { | ||
2464 | struct drm_buf *buf; | ||
2465 | |||
2466 | *buffer = NULL; | ||
2467 | buf = radeon_freelist_get(dev); | ||
2468 | if (!buf) { | ||
2469 | return -EBUSY; | ||
2470 | } | ||
2471 | buf->file_priv = fpriv; | ||
2472 | *buffer = buf; | ||
2473 | return 0; | ||
2474 | } | ||
2475 | |||
2476 | static void r600_ib_free(struct drm_device *dev, struct drm_buf *buf, | ||
2477 | struct drm_file *fpriv, int l, int r) | ||
2478 | { | ||
2479 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
2480 | |||
2481 | if (buf) { | ||
2482 | if (!r) | ||
2483 | r600_cp_dispatch_indirect(dev, buf, 0, l * 4); | ||
2484 | radeon_cp_discard_buffer(dev, fpriv->master, buf); | ||
2485 | COMMIT_RING(); | ||
2486 | } | ||
2487 | } | ||
2488 | |||
2489 | int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) | ||
2490 | { | ||
2491 | struct drm_radeon_private *dev_priv = dev->dev_private; | ||
2492 | struct drm_radeon_cs *cs = data; | ||
2493 | struct drm_buf *buf; | ||
2494 | unsigned family; | ||
2495 | int l, r = 0; | ||
2496 | u32 *ib, cs_id = 0; | ||
2497 | |||
2498 | if (dev_priv == NULL) { | ||
2499 | DRM_ERROR("called with no initialization\n"); | ||
2500 | return -EINVAL; | ||
2501 | } | ||
2502 | family = dev_priv->flags & RADEON_FAMILY_MASK; | ||
2503 | if (family < CHIP_R600) { | ||
2504 | DRM_ERROR("cs ioctl valid only for R6XX & R7XX in legacy mode\n"); | ||
2505 | return -EINVAL; | ||
2506 | } | ||
2507 | mutex_lock(&dev_priv->cs_mutex); | ||
2508 | /* get ib */ | ||
2509 | r = r600_ib_get(dev, fpriv, &buf); | ||
2510 | if (r) { | ||
2511 | DRM_ERROR("ib_get failed\n"); | ||
2512 | goto out; | ||
2513 | } | ||
2514 | ib = dev->agp_buffer_map->handle + buf->offset; | ||
2515 | /* now parse command stream */ | ||
2516 | r = r600_cs_legacy(dev, data, fpriv, family, ib, &l); | ||
2517 | if (r) { | ||
2518 | goto out; | ||
2519 | } | ||
2520 | |||
2521 | out: | ||
2522 | r600_ib_free(dev, buf, fpriv, l, r); | ||
2523 | /* emit cs id sequence */ | ||
2524 | r600_cs_id_emit(dev_priv, &cs_id); | ||
2525 | cs->cs_id = cs_id; | ||
2526 | mutex_unlock(&dev_priv->cs_mutex); | ||
2527 | return r; | ||
2528 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c new file mode 100644 index 000000000000..39bf6349351b --- /dev/null +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -0,0 +1,658 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * Copyright 2009 Jerome Glisse. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: Dave Airlie | ||
25 | * Alex Deucher | ||
26 | * Jerome Glisse | ||
27 | */ | ||
28 | #include "drmP.h" | ||
29 | #include "radeon.h" | ||
30 | #include "radeon_share.h" | ||
31 | #include "r600d.h" | ||
32 | #include "avivod.h" | ||
33 | |||
34 | static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, | ||
35 | struct radeon_cs_reloc **cs_reloc); | ||
36 | static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | ||
37 | struct radeon_cs_reloc **cs_reloc); | ||
38 | typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); | ||
39 | static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; | ||
40 | |||
41 | /** | ||
42 | * r600_cs_packet_parse() - parse cp packet and point ib index to next packet | ||
43 | * @parser: parser structure holding parsing context. | ||
44 | * @pkt: where to store packet informations | ||
45 | * | ||
46 | * Assume that chunk_ib_index is properly set. Will return -EINVAL | ||
47 | * if packet is bigger than remaining ib size. or if packets is unknown. | ||
48 | **/ | ||
49 | int r600_cs_packet_parse(struct radeon_cs_parser *p, | ||
50 | struct radeon_cs_packet *pkt, | ||
51 | unsigned idx) | ||
52 | { | ||
53 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
54 | uint32_t header; | ||
55 | |||
56 | if (idx >= ib_chunk->length_dw) { | ||
57 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", | ||
58 | idx, ib_chunk->length_dw); | ||
59 | return -EINVAL; | ||
60 | } | ||
61 | header = ib_chunk->kdata[idx]; | ||
62 | pkt->idx = idx; | ||
63 | pkt->type = CP_PACKET_GET_TYPE(header); | ||
64 | pkt->count = CP_PACKET_GET_COUNT(header); | ||
65 | pkt->one_reg_wr = 0; | ||
66 | switch (pkt->type) { | ||
67 | case PACKET_TYPE0: | ||
68 | pkt->reg = CP_PACKET0_GET_REG(header); | ||
69 | break; | ||
70 | case PACKET_TYPE3: | ||
71 | pkt->opcode = CP_PACKET3_GET_OPCODE(header); | ||
72 | break; | ||
73 | case PACKET_TYPE2: | ||
74 | pkt->count = -1; | ||
75 | break; | ||
76 | default: | ||
77 | DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { | ||
81 | DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", | ||
82 | pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); | ||
83 | return -EINVAL; | ||
84 | } | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3 | ||
90 | * @parser: parser structure holding parsing context. | ||
91 | * @data: pointer to relocation data | ||
92 | * @offset_start: starting offset | ||
93 | * @offset_mask: offset mask (to align start offset on) | ||
94 | * @reloc: reloc informations | ||
95 | * | ||
96 | * Check next packet is relocation packet3, do bo validation and compute | ||
97 | * GPU offset using the provided start. | ||
98 | **/ | ||
99 | static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, | ||
100 | struct radeon_cs_reloc **cs_reloc) | ||
101 | { | ||
102 | struct radeon_cs_chunk *ib_chunk; | ||
103 | struct radeon_cs_chunk *relocs_chunk; | ||
104 | struct radeon_cs_packet p3reloc; | ||
105 | unsigned idx; | ||
106 | int r; | ||
107 | |||
108 | if (p->chunk_relocs_idx == -1) { | ||
109 | DRM_ERROR("No relocation chunk !\n"); | ||
110 | return -EINVAL; | ||
111 | } | ||
112 | *cs_reloc = NULL; | ||
113 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
114 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | ||
115 | r = r600_cs_packet_parse(p, &p3reloc, p->idx); | ||
116 | if (r) { | ||
117 | return r; | ||
118 | } | ||
119 | p->idx += p3reloc.count + 2; | ||
120 | if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { | ||
121 | DRM_ERROR("No packet3 for relocation for packet at %d.\n", | ||
122 | p3reloc.idx); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | idx = ib_chunk->kdata[p3reloc.idx + 1]; | ||
126 | if (idx >= relocs_chunk->length_dw) { | ||
127 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | ||
128 | idx, relocs_chunk->length_dw); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | /* FIXME: we assume reloc size is 4 dwords */ | ||
132 | *cs_reloc = p->relocs_ptr[(idx / 4)]; | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3 | ||
138 | * @parser: parser structure holding parsing context. | ||
139 | * @data: pointer to relocation data | ||
140 | * @offset_start: starting offset | ||
141 | * @offset_mask: offset mask (to align start offset on) | ||
142 | * @reloc: reloc informations | ||
143 | * | ||
144 | * Check next packet is relocation packet3, do bo validation and compute | ||
145 | * GPU offset using the provided start. | ||
146 | **/ | ||
147 | static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | ||
148 | struct radeon_cs_reloc **cs_reloc) | ||
149 | { | ||
150 | struct radeon_cs_chunk *ib_chunk; | ||
151 | struct radeon_cs_chunk *relocs_chunk; | ||
152 | struct radeon_cs_packet p3reloc; | ||
153 | unsigned idx; | ||
154 | int r; | ||
155 | |||
156 | if (p->chunk_relocs_idx == -1) { | ||
157 | DRM_ERROR("No relocation chunk !\n"); | ||
158 | return -EINVAL; | ||
159 | } | ||
160 | *cs_reloc = NULL; | ||
161 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
162 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | ||
163 | r = r600_cs_packet_parse(p, &p3reloc, p->idx); | ||
164 | if (r) { | ||
165 | return r; | ||
166 | } | ||
167 | p->idx += p3reloc.count + 2; | ||
168 | if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { | ||
169 | DRM_ERROR("No packet3 for relocation for packet at %d.\n", | ||
170 | p3reloc.idx); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | idx = ib_chunk->kdata[p3reloc.idx + 1]; | ||
174 | if (idx >= relocs_chunk->length_dw) { | ||
175 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | ||
176 | idx, relocs_chunk->length_dw); | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | *cs_reloc = &p->relocs[0]; | ||
180 | (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32; | ||
181 | (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int r600_packet0_check(struct radeon_cs_parser *p, | ||
186 | struct radeon_cs_packet *pkt, | ||
187 | unsigned idx, unsigned reg) | ||
188 | { | ||
189 | switch (reg) { | ||
190 | case AVIVO_D1MODE_VLINE_START_END: | ||
191 | case AVIVO_D2MODE_VLINE_START_END: | ||
192 | break; | ||
193 | default: | ||
194 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | ||
195 | reg, idx); | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static int r600_cs_parse_packet0(struct radeon_cs_parser *p, | ||
202 | struct radeon_cs_packet *pkt) | ||
203 | { | ||
204 | unsigned reg, i; | ||
205 | unsigned idx; | ||
206 | int r; | ||
207 | |||
208 | idx = pkt->idx + 1; | ||
209 | reg = pkt->reg; | ||
210 | for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { | ||
211 | r = r600_packet0_check(p, pkt, idx, reg); | ||
212 | if (r) { | ||
213 | return r; | ||
214 | } | ||
215 | } | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static int r600_packet3_check(struct radeon_cs_parser *p, | ||
220 | struct radeon_cs_packet *pkt) | ||
221 | { | ||
222 | struct radeon_cs_chunk *ib_chunk; | ||
223 | struct radeon_cs_reloc *reloc; | ||
224 | volatile u32 *ib; | ||
225 | unsigned idx; | ||
226 | unsigned i; | ||
227 | unsigned start_reg, end_reg, reg; | ||
228 | int r; | ||
229 | |||
230 | ib = p->ib->ptr; | ||
231 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
232 | idx = pkt->idx + 1; | ||
233 | switch (pkt->opcode) { | ||
234 | case PACKET3_START_3D_CMDBUF: | ||
235 | if (p->family >= CHIP_RV770 || pkt->count) { | ||
236 | DRM_ERROR("bad START_3D\n"); | ||
237 | return -EINVAL; | ||
238 | } | ||
239 | break; | ||
240 | case PACKET3_CONTEXT_CONTROL: | ||
241 | if (pkt->count != 1) { | ||
242 | DRM_ERROR("bad CONTEXT_CONTROL\n"); | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | break; | ||
246 | case PACKET3_INDEX_TYPE: | ||
247 | case PACKET3_NUM_INSTANCES: | ||
248 | if (pkt->count) { | ||
249 | DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n"); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | break; | ||
253 | case PACKET3_DRAW_INDEX: | ||
254 | if (pkt->count != 3) { | ||
255 | DRM_ERROR("bad DRAW_INDEX\n"); | ||
256 | return -EINVAL; | ||
257 | } | ||
258 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
259 | if (r) { | ||
260 | DRM_ERROR("bad DRAW_INDEX\n"); | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | ib[idx+0] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
264 | ib[idx+1] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
265 | break; | ||
266 | case PACKET3_DRAW_INDEX_AUTO: | ||
267 | if (pkt->count != 1) { | ||
268 | DRM_ERROR("bad DRAW_INDEX_AUTO\n"); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | break; | ||
272 | case PACKET3_DRAW_INDEX_IMMD_BE: | ||
273 | case PACKET3_DRAW_INDEX_IMMD: | ||
274 | if (pkt->count < 2) { | ||
275 | DRM_ERROR("bad DRAW_INDEX_IMMD\n"); | ||
276 | return -EINVAL; | ||
277 | } | ||
278 | break; | ||
279 | case PACKET3_WAIT_REG_MEM: | ||
280 | if (pkt->count != 5) { | ||
281 | DRM_ERROR("bad WAIT_REG_MEM\n"); | ||
282 | return -EINVAL; | ||
283 | } | ||
284 | /* bit 4 is reg (0) or mem (1) */ | ||
285 | if (ib_chunk->kdata[idx+0] & 0x10) { | ||
286 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
287 | if (r) { | ||
288 | DRM_ERROR("bad WAIT_REG_MEM\n"); | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
292 | ib[idx+2] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
293 | } | ||
294 | break; | ||
295 | case PACKET3_SURFACE_SYNC: | ||
296 | if (pkt->count != 3) { | ||
297 | DRM_ERROR("bad SURFACE_SYNC\n"); | ||
298 | return -EINVAL; | ||
299 | } | ||
300 | /* 0xffffffff/0x0 is flush all cache flag */ | ||
301 | if (ib_chunk->kdata[idx+1] != 0xffffffff || | ||
302 | ib_chunk->kdata[idx+2] != 0) { | ||
303 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
304 | if (r) { | ||
305 | DRM_ERROR("bad SURFACE_SYNC\n"); | ||
306 | return -EINVAL; | ||
307 | } | ||
308 | ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
309 | } | ||
310 | break; | ||
311 | case PACKET3_EVENT_WRITE: | ||
312 | if (pkt->count != 2 && pkt->count != 0) { | ||
313 | DRM_ERROR("bad EVENT_WRITE\n"); | ||
314 | return -EINVAL; | ||
315 | } | ||
316 | if (pkt->count) { | ||
317 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
318 | if (r) { | ||
319 | DRM_ERROR("bad EVENT_WRITE\n"); | ||
320 | return -EINVAL; | ||
321 | } | ||
322 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
323 | ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
324 | } | ||
325 | break; | ||
326 | case PACKET3_EVENT_WRITE_EOP: | ||
327 | if (pkt->count != 4) { | ||
328 | DRM_ERROR("bad EVENT_WRITE_EOP\n"); | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
332 | if (r) { | ||
333 | DRM_ERROR("bad EVENT_WRITE\n"); | ||
334 | return -EINVAL; | ||
335 | } | ||
336 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
337 | ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
338 | break; | ||
339 | case PACKET3_SET_CONFIG_REG: | ||
340 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONFIG_REG_OFFSET; | ||
341 | end_reg = 4 * pkt->count + start_reg - 4; | ||
342 | if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) || | ||
343 | (start_reg >= PACKET3_SET_CONFIG_REG_END) || | ||
344 | (end_reg >= PACKET3_SET_CONFIG_REG_END)) { | ||
345 | DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | for (i = 0; i < pkt->count; i++) { | ||
349 | reg = start_reg + (4 * i); | ||
350 | switch (reg) { | ||
351 | case CP_COHER_BASE: | ||
352 | /* use PACKET3_SURFACE_SYNC */ | ||
353 | return -EINVAL; | ||
354 | default: | ||
355 | break; | ||
356 | } | ||
357 | } | ||
358 | break; | ||
359 | case PACKET3_SET_CONTEXT_REG: | ||
360 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONTEXT_REG_OFFSET; | ||
361 | end_reg = 4 * pkt->count + start_reg - 4; | ||
362 | if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) || | ||
363 | (start_reg >= PACKET3_SET_CONTEXT_REG_END) || | ||
364 | (end_reg >= PACKET3_SET_CONTEXT_REG_END)) { | ||
365 | DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n"); | ||
366 | return -EINVAL; | ||
367 | } | ||
368 | for (i = 0; i < pkt->count; i++) { | ||
369 | reg = start_reg + (4 * i); | ||
370 | switch (reg) { | ||
371 | case DB_DEPTH_BASE: | ||
372 | case CB_COLOR0_BASE: | ||
373 | case CB_COLOR1_BASE: | ||
374 | case CB_COLOR2_BASE: | ||
375 | case CB_COLOR3_BASE: | ||
376 | case CB_COLOR4_BASE: | ||
377 | case CB_COLOR5_BASE: | ||
378 | case CB_COLOR6_BASE: | ||
379 | case CB_COLOR7_BASE: | ||
380 | case SQ_PGM_START_FS: | ||
381 | case SQ_PGM_START_ES: | ||
382 | case SQ_PGM_START_VS: | ||
383 | case SQ_PGM_START_GS: | ||
384 | case SQ_PGM_START_PS: | ||
385 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
386 | if (r) { | ||
387 | DRM_ERROR("bad SET_CONTEXT_REG " | ||
388 | "0x%04X\n", reg); | ||
389 | return -EINVAL; | ||
390 | } | ||
391 | ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
392 | break; | ||
393 | case VGT_DMA_BASE: | ||
394 | case VGT_DMA_BASE_HI: | ||
395 | /* These should be handled by DRAW_INDEX packet 3 */ | ||
396 | case VGT_STRMOUT_BASE_OFFSET_0: | ||
397 | case VGT_STRMOUT_BASE_OFFSET_1: | ||
398 | case VGT_STRMOUT_BASE_OFFSET_2: | ||
399 | case VGT_STRMOUT_BASE_OFFSET_3: | ||
400 | case VGT_STRMOUT_BASE_OFFSET_HI_0: | ||
401 | case VGT_STRMOUT_BASE_OFFSET_HI_1: | ||
402 | case VGT_STRMOUT_BASE_OFFSET_HI_2: | ||
403 | case VGT_STRMOUT_BASE_OFFSET_HI_3: | ||
404 | case VGT_STRMOUT_BUFFER_BASE_0: | ||
405 | case VGT_STRMOUT_BUFFER_BASE_1: | ||
406 | case VGT_STRMOUT_BUFFER_BASE_2: | ||
407 | case VGT_STRMOUT_BUFFER_BASE_3: | ||
408 | case VGT_STRMOUT_BUFFER_OFFSET_0: | ||
409 | case VGT_STRMOUT_BUFFER_OFFSET_1: | ||
410 | case VGT_STRMOUT_BUFFER_OFFSET_2: | ||
411 | case VGT_STRMOUT_BUFFER_OFFSET_3: | ||
412 | /* These should be handled by STRMOUT_BUFFER packet 3 */ | ||
413 | DRM_ERROR("bad context reg: 0x%08x\n", reg); | ||
414 | return -EINVAL; | ||
415 | default: | ||
416 | break; | ||
417 | } | ||
418 | } | ||
419 | break; | ||
420 | case PACKET3_SET_RESOURCE: | ||
421 | if (pkt->count % 7) { | ||
422 | DRM_ERROR("bad SET_RESOURCE\n"); | ||
423 | return -EINVAL; | ||
424 | } | ||
425 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_RESOURCE_OFFSET; | ||
426 | end_reg = 4 * pkt->count + start_reg - 4; | ||
427 | if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) || | ||
428 | (start_reg >= PACKET3_SET_RESOURCE_END) || | ||
429 | (end_reg >= PACKET3_SET_RESOURCE_END)) { | ||
430 | DRM_ERROR("bad SET_RESOURCE\n"); | ||
431 | return -EINVAL; | ||
432 | } | ||
433 | for (i = 0; i < (pkt->count / 7); i++) { | ||
434 | switch (G__SQ_VTX_CONSTANT_TYPE(ib[idx+(i*7)+6+1])) { | ||
435 | case SQ_TEX_VTX_VALID_TEXTURE: | ||
436 | /* tex base */ | ||
437 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
438 | if (r) { | ||
439 | DRM_ERROR("bad SET_RESOURCE\n"); | ||
440 | return -EINVAL; | ||
441 | } | ||
442 | ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
443 | /* tex mip base */ | ||
444 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
445 | if (r) { | ||
446 | DRM_ERROR("bad SET_RESOURCE\n"); | ||
447 | return -EINVAL; | ||
448 | } | ||
449 | ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
450 | break; | ||
451 | case SQ_TEX_VTX_VALID_BUFFER: | ||
452 | /* vtx base */ | ||
453 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
454 | if (r) { | ||
455 | DRM_ERROR("bad SET_RESOURCE\n"); | ||
456 | return -EINVAL; | ||
457 | } | ||
458 | ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); | ||
459 | ib[idx+1+(i*7)+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
460 | break; | ||
461 | case SQ_TEX_VTX_INVALID_TEXTURE: | ||
462 | case SQ_TEX_VTX_INVALID_BUFFER: | ||
463 | default: | ||
464 | DRM_ERROR("bad SET_RESOURCE\n"); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | } | ||
468 | break; | ||
469 | case PACKET3_SET_ALU_CONST: | ||
470 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_ALU_CONST_OFFSET; | ||
471 | end_reg = 4 * pkt->count + start_reg - 4; | ||
472 | if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || | ||
473 | (start_reg >= PACKET3_SET_ALU_CONST_END) || | ||
474 | (end_reg >= PACKET3_SET_ALU_CONST_END)) { | ||
475 | DRM_ERROR("bad SET_ALU_CONST\n"); | ||
476 | return -EINVAL; | ||
477 | } | ||
478 | break; | ||
479 | case PACKET3_SET_BOOL_CONST: | ||
480 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_BOOL_CONST_OFFSET; | ||
481 | end_reg = 4 * pkt->count + start_reg - 4; | ||
482 | if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) || | ||
483 | (start_reg >= PACKET3_SET_BOOL_CONST_END) || | ||
484 | (end_reg >= PACKET3_SET_BOOL_CONST_END)) { | ||
485 | DRM_ERROR("bad SET_BOOL_CONST\n"); | ||
486 | return -EINVAL; | ||
487 | } | ||
488 | break; | ||
489 | case PACKET3_SET_LOOP_CONST: | ||
490 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_LOOP_CONST_OFFSET; | ||
491 | end_reg = 4 * pkt->count + start_reg - 4; | ||
492 | if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) || | ||
493 | (start_reg >= PACKET3_SET_LOOP_CONST_END) || | ||
494 | (end_reg >= PACKET3_SET_LOOP_CONST_END)) { | ||
495 | DRM_ERROR("bad SET_LOOP_CONST\n"); | ||
496 | return -EINVAL; | ||
497 | } | ||
498 | break; | ||
499 | case PACKET3_SET_CTL_CONST: | ||
500 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_CTL_CONST_OFFSET; | ||
501 | end_reg = 4 * pkt->count + start_reg - 4; | ||
502 | if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) || | ||
503 | (start_reg >= PACKET3_SET_CTL_CONST_END) || | ||
504 | (end_reg >= PACKET3_SET_CTL_CONST_END)) { | ||
505 | DRM_ERROR("bad SET_CTL_CONST\n"); | ||
506 | return -EINVAL; | ||
507 | } | ||
508 | break; | ||
509 | case PACKET3_SET_SAMPLER: | ||
510 | if (pkt->count % 3) { | ||
511 | DRM_ERROR("bad SET_SAMPLER\n"); | ||
512 | return -EINVAL; | ||
513 | } | ||
514 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_SAMPLER_OFFSET; | ||
515 | end_reg = 4 * pkt->count + start_reg - 4; | ||
516 | if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) || | ||
517 | (start_reg >= PACKET3_SET_SAMPLER_END) || | ||
518 | (end_reg >= PACKET3_SET_SAMPLER_END)) { | ||
519 | DRM_ERROR("bad SET_SAMPLER\n"); | ||
520 | return -EINVAL; | ||
521 | } | ||
522 | break; | ||
523 | case PACKET3_SURFACE_BASE_UPDATE: | ||
524 | if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { | ||
525 | DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); | ||
526 | return -EINVAL; | ||
527 | } | ||
528 | if (pkt->count) { | ||
529 | DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); | ||
530 | return -EINVAL; | ||
531 | } | ||
532 | break; | ||
533 | case PACKET3_NOP: | ||
534 | break; | ||
535 | default: | ||
536 | DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | int r600_cs_parse(struct radeon_cs_parser *p) | ||
543 | { | ||
544 | struct radeon_cs_packet pkt; | ||
545 | int r; | ||
546 | |||
547 | do { | ||
548 | r = r600_cs_packet_parse(p, &pkt, p->idx); | ||
549 | if (r) { | ||
550 | return r; | ||
551 | } | ||
552 | p->idx += pkt.count + 2; | ||
553 | switch (pkt.type) { | ||
554 | case PACKET_TYPE0: | ||
555 | r = r600_cs_parse_packet0(p, &pkt); | ||
556 | break; | ||
557 | case PACKET_TYPE2: | ||
558 | break; | ||
559 | case PACKET_TYPE3: | ||
560 | r = r600_packet3_check(p, &pkt); | ||
561 | break; | ||
562 | default: | ||
563 | DRM_ERROR("Unknown packet type %d !\n", pkt.type); | ||
564 | return -EINVAL; | ||
565 | } | ||
566 | if (r) { | ||
567 | return r; | ||
568 | } | ||
569 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | ||
570 | #if 0 | ||
571 | for (r = 0; r < p->ib->length_dw; r++) { | ||
572 | printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]); | ||
573 | mdelay(1); | ||
574 | } | ||
575 | #endif | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) | ||
580 | { | ||
581 | if (p->chunk_relocs_idx == -1) { | ||
582 | return 0; | ||
583 | } | ||
584 | p->relocs = kcalloc(1, sizeof(struct radeon_cs_reloc), GFP_KERNEL); | ||
585 | if (p->relocs == NULL) { | ||
586 | return -ENOMEM; | ||
587 | } | ||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | /** | ||
592 | * cs_parser_fini() - clean parser states | ||
593 | * @parser: parser structure holding parsing context. | ||
594 | * @error: error number | ||
595 | * | ||
596 | * If error is set than unvalidate buffer, otherwise just free memory | ||
597 | * used by parsing context. | ||
598 | **/ | ||
599 | static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) | ||
600 | { | ||
601 | unsigned i; | ||
602 | |||
603 | kfree(parser->relocs); | ||
604 | for (i = 0; i < parser->nchunks; i++) { | ||
605 | kfree(parser->chunks[i].kdata); | ||
606 | } | ||
607 | kfree(parser->chunks); | ||
608 | kfree(parser->chunks_array); | ||
609 | } | ||
610 | |||
611 | int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, | ||
612 | unsigned family, u32 *ib, int *l) | ||
613 | { | ||
614 | struct radeon_cs_parser parser; | ||
615 | struct radeon_cs_chunk *ib_chunk; | ||
616 | struct radeon_ib fake_ib; | ||
617 | int r; | ||
618 | |||
619 | /* initialize parser */ | ||
620 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); | ||
621 | parser.filp = filp; | ||
622 | parser.rdev = NULL; | ||
623 | parser.family = family; | ||
624 | parser.ib = &fake_ib; | ||
625 | fake_ib.ptr = ib; | ||
626 | r = radeon_cs_parser_init(&parser, data); | ||
627 | if (r) { | ||
628 | DRM_ERROR("Failed to initialize parser !\n"); | ||
629 | r600_cs_parser_fini(&parser, r); | ||
630 | return r; | ||
631 | } | ||
632 | r = r600_cs_parser_relocs_legacy(&parser); | ||
633 | if (r) { | ||
634 | DRM_ERROR("Failed to parse relocation !\n"); | ||
635 | r600_cs_parser_fini(&parser, r); | ||
636 | return r; | ||
637 | } | ||
638 | /* Copy the packet into the IB, the parser will read from the | ||
639 | * input memory (cached) and write to the IB (which can be | ||
640 | * uncached). */ | ||
641 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; | ||
642 | parser.ib->length_dw = ib_chunk->length_dw; | ||
643 | memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4); | ||
644 | *l = parser.ib->length_dw; | ||
645 | r = r600_cs_parse(&parser); | ||
646 | if (r) { | ||
647 | DRM_ERROR("Invalid command stream !\n"); | ||
648 | r600_cs_parser_fini(&parser, r); | ||
649 | return r; | ||
650 | } | ||
651 | r600_cs_parser_fini(&parser, r); | ||
652 | return r; | ||
653 | } | ||
654 | |||
655 | void r600_cs_legacy_init(void) | ||
656 | { | ||
657 | r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm; | ||
658 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h new file mode 100644 index 000000000000..723295f59281 --- /dev/null +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -0,0 +1,661 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2009 Red Hat Inc. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice shall be included in | ||
13 | * all copies or substantial portions of the Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
21 | * OTHER DEALINGS IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: Dave Airlie | ||
24 | * Alex Deucher | ||
25 | * Jerome Glisse | ||
26 | */ | ||
27 | #ifndef R600D_H | ||
28 | #define R600D_H | ||
29 | |||
30 | #define CP_PACKET2 0x80000000 | ||
31 | #define PACKET2_PAD_SHIFT 0 | ||
32 | #define PACKET2_PAD_MASK (0x3fffffff << 0) | ||
33 | |||
34 | #define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) | ||
35 | |||
36 | #define R6XX_MAX_SH_GPRS 256 | ||
37 | #define R6XX_MAX_TEMP_GPRS 16 | ||
38 | #define R6XX_MAX_SH_THREADS 256 | ||
39 | #define R6XX_MAX_SH_STACK_ENTRIES 4096 | ||
40 | #define R6XX_MAX_BACKENDS 8 | ||
41 | #define R6XX_MAX_BACKENDS_MASK 0xff | ||
42 | #define R6XX_MAX_SIMDS 8 | ||
43 | #define R6XX_MAX_SIMDS_MASK 0xff | ||
44 | #define R6XX_MAX_PIPES 8 | ||
45 | #define R6XX_MAX_PIPES_MASK 0xff | ||
46 | |||
47 | /* PTE flags */ | ||
48 | #define PTE_VALID (1 << 0) | ||
49 | #define PTE_SYSTEM (1 << 1) | ||
50 | #define PTE_SNOOPED (1 << 2) | ||
51 | #define PTE_READABLE (1 << 5) | ||
52 | #define PTE_WRITEABLE (1 << 6) | ||
53 | |||
54 | /* Registers */ | ||
55 | #define ARB_POP 0x2418 | ||
56 | #define ENABLE_TC128 (1 << 30) | ||
57 | #define ARB_GDEC_RD_CNTL 0x246C | ||
58 | |||
59 | #define CC_GC_SHADER_PIPE_CONFIG 0x8950 | ||
60 | #define CC_RB_BACKEND_DISABLE 0x98F4 | ||
61 | #define BACKEND_DISABLE(x) ((x) << 16) | ||
62 | |||
63 | #define CB_COLOR0_BASE 0x28040 | ||
64 | #define CB_COLOR1_BASE 0x28044 | ||
65 | #define CB_COLOR2_BASE 0x28048 | ||
66 | #define CB_COLOR3_BASE 0x2804C | ||
67 | #define CB_COLOR4_BASE 0x28050 | ||
68 | #define CB_COLOR5_BASE 0x28054 | ||
69 | #define CB_COLOR6_BASE 0x28058 | ||
70 | #define CB_COLOR7_BASE 0x2805C | ||
71 | #define CB_COLOR7_FRAG 0x280FC | ||
72 | |||
73 | #define CB_COLOR0_SIZE 0x28060 | ||
74 | #define CB_COLOR0_VIEW 0x28080 | ||
75 | #define CB_COLOR0_INFO 0x280a0 | ||
76 | #define CB_COLOR0_TILE 0x280c0 | ||
77 | #define CB_COLOR0_FRAG 0x280e0 | ||
78 | #define CB_COLOR0_MASK 0x28100 | ||
79 | |||
80 | #define CONFIG_MEMSIZE 0x5428 | ||
81 | #define CP_STAT 0x8680 | ||
82 | #define CP_COHER_BASE 0x85F8 | ||
83 | #define CP_DEBUG 0xC1FC | ||
84 | #define R_0086D8_CP_ME_CNTL 0x86D8 | ||
85 | #define S_0086D8_CP_ME_HALT(x) (((x) & 1)<<28) | ||
86 | #define C_0086D8_CP_ME_HALT(x) ((x) & 0xEFFFFFFF) | ||
87 | #define CP_ME_RAM_DATA 0xC160 | ||
88 | #define CP_ME_RAM_RADDR 0xC158 | ||
89 | #define CP_ME_RAM_WADDR 0xC15C | ||
90 | #define CP_MEQ_THRESHOLDS 0x8764 | ||
91 | #define MEQ_END(x) ((x) << 16) | ||
92 | #define ROQ_END(x) ((x) << 24) | ||
93 | #define CP_PERFMON_CNTL 0x87FC | ||
94 | #define CP_PFP_UCODE_ADDR 0xC150 | ||
95 | #define CP_PFP_UCODE_DATA 0xC154 | ||
96 | #define CP_QUEUE_THRESHOLDS 0x8760 | ||
97 | #define ROQ_IB1_START(x) ((x) << 0) | ||
98 | #define ROQ_IB2_START(x) ((x) << 8) | ||
99 | #define CP_RB_BASE 0xC100 | ||
100 | #define CP_RB_CNTL 0xC104 | ||
101 | #define RB_BUFSZ(x) ((x)<<0) | ||
102 | #define RB_BLKSZ(x) ((x)<<8) | ||
103 | #define RB_NO_UPDATE (1<<27) | ||
104 | #define RB_RPTR_WR_ENA (1<<31) | ||
105 | #define BUF_SWAP_32BIT (2 << 16) | ||
106 | #define CP_RB_RPTR 0x8700 | ||
107 | #define CP_RB_RPTR_ADDR 0xC10C | ||
108 | #define CP_RB_RPTR_ADDR_HI 0xC110 | ||
109 | #define CP_RB_RPTR_WR 0xC108 | ||
110 | #define CP_RB_WPTR 0xC114 | ||
111 | #define CP_RB_WPTR_ADDR 0xC118 | ||
112 | #define CP_RB_WPTR_ADDR_HI 0xC11C | ||
113 | #define CP_RB_WPTR_DELAY 0x8704 | ||
114 | #define CP_ROQ_IB1_STAT 0x8784 | ||
115 | #define CP_ROQ_IB2_STAT 0x8788 | ||
116 | #define CP_SEM_WAIT_TIMER 0x85BC | ||
117 | |||
118 | #define DB_DEBUG 0x9830 | ||
119 | #define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) | ||
120 | #define DB_DEPTH_BASE 0x2800C | ||
121 | #define DB_WATERMARKS 0x9838 | ||
122 | #define DEPTH_FREE(x) ((x) << 0) | ||
123 | #define DEPTH_FLUSH(x) ((x) << 5) | ||
124 | #define DEPTH_PENDING_FREE(x) ((x) << 15) | ||
125 | #define DEPTH_CACHELINE_FREE(x) ((x) << 20) | ||
126 | |||
127 | #define DCP_TILING_CONFIG 0x6CA0 | ||
128 | #define PIPE_TILING(x) ((x) << 1) | ||
129 | #define BANK_TILING(x) ((x) << 4) | ||
130 | #define GROUP_SIZE(x) ((x) << 6) | ||
131 | #define ROW_TILING(x) ((x) << 8) | ||
132 | #define BANK_SWAPS(x) ((x) << 11) | ||
133 | #define SAMPLE_SPLIT(x) ((x) << 14) | ||
134 | #define BACKEND_MAP(x) ((x) << 16) | ||
135 | |||
136 | #define GB_TILING_CONFIG 0x98F0 | ||
137 | |||
138 | #define GC_USER_SHADER_PIPE_CONFIG 0x8954 | ||
139 | #define INACTIVE_QD_PIPES(x) ((x) << 8) | ||
140 | #define INACTIVE_QD_PIPES_MASK 0x0000FF00 | ||
141 | #define INACTIVE_SIMDS(x) ((x) << 16) | ||
142 | #define INACTIVE_SIMDS_MASK 0x00FF0000 | ||
143 | |||
144 | #define SQ_CONFIG 0x8c00 | ||
145 | # define VC_ENABLE (1 << 0) | ||
146 | # define EXPORT_SRC_C (1 << 1) | ||
147 | # define DX9_CONSTS (1 << 2) | ||
148 | # define ALU_INST_PREFER_VECTOR (1 << 3) | ||
149 | # define DX10_CLAMP (1 << 4) | ||
150 | # define CLAUSE_SEQ_PRIO(x) ((x) << 8) | ||
151 | # define PS_PRIO(x) ((x) << 24) | ||
152 | # define VS_PRIO(x) ((x) << 26) | ||
153 | # define GS_PRIO(x) ((x) << 28) | ||
154 | # define ES_PRIO(x) ((x) << 30) | ||
155 | #define SQ_GPR_RESOURCE_MGMT_1 0x8c04 | ||
156 | # define NUM_PS_GPRS(x) ((x) << 0) | ||
157 | # define NUM_VS_GPRS(x) ((x) << 16) | ||
158 | # define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) | ||
159 | #define SQ_GPR_RESOURCE_MGMT_2 0x8c08 | ||
160 | # define NUM_GS_GPRS(x) ((x) << 0) | ||
161 | # define NUM_ES_GPRS(x) ((x) << 16) | ||
162 | #define SQ_THREAD_RESOURCE_MGMT 0x8c0c | ||
163 | # define NUM_PS_THREADS(x) ((x) << 0) | ||
164 | # define NUM_VS_THREADS(x) ((x) << 8) | ||
165 | # define NUM_GS_THREADS(x) ((x) << 16) | ||
166 | # define NUM_ES_THREADS(x) ((x) << 24) | ||
167 | #define SQ_STACK_RESOURCE_MGMT_1 0x8c10 | ||
168 | # define NUM_PS_STACK_ENTRIES(x) ((x) << 0) | ||
169 | # define NUM_VS_STACK_ENTRIES(x) ((x) << 16) | ||
170 | #define SQ_STACK_RESOURCE_MGMT_2 0x8c14 | ||
171 | # define NUM_GS_STACK_ENTRIES(x) ((x) << 0) | ||
172 | # define NUM_ES_STACK_ENTRIES(x) ((x) << 16) | ||
173 | |||
174 | #define GRBM_CNTL 0x8000 | ||
175 | # define GRBM_READ_TIMEOUT(x) ((x) << 0) | ||
176 | #define GRBM_STATUS 0x8010 | ||
177 | #define CMDFIFO_AVAIL_MASK 0x0000001F | ||
178 | #define GUI_ACTIVE (1<<31) | ||
179 | #define GRBM_STATUS2 0x8014 | ||
180 | #define GRBM_SOFT_RESET 0x8020 | ||
181 | #define SOFT_RESET_CP (1<<0) | ||
182 | |||
183 | #define HDP_HOST_PATH_CNTL 0x2C00 | ||
184 | #define HDP_NONSURFACE_BASE 0x2C04 | ||
185 | #define HDP_NONSURFACE_INFO 0x2C08 | ||
186 | #define HDP_NONSURFACE_SIZE 0x2C0C | ||
187 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 | ||
188 | #define HDP_TILING_CONFIG 0x2F3C | ||
189 | |||
190 | #define MC_VM_AGP_TOP 0x2184 | ||
191 | #define MC_VM_AGP_BOT 0x2188 | ||
192 | #define MC_VM_AGP_BASE 0x218C | ||
193 | #define MC_VM_FB_LOCATION 0x2180 | ||
194 | #define MC_VM_L1_TLB_MCD_RD_A_CNTL 0x219C | ||
195 | #define ENABLE_L1_TLB (1 << 0) | ||
196 | #define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) | ||
197 | #define ENABLE_L1_STRICT_ORDERING (1 << 2) | ||
198 | #define SYSTEM_ACCESS_MODE_MASK 0x000000C0 | ||
199 | #define SYSTEM_ACCESS_MODE_SHIFT 6 | ||
200 | #define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) | ||
201 | #define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) | ||
202 | #define SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) | ||
203 | #define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) | ||
204 | #define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) | ||
205 | #define SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) | ||
206 | #define ENABLE_SEMAPHORE_MODE (1 << 10) | ||
207 | #define ENABLE_WAIT_L2_QUERY (1 << 11) | ||
208 | #define EFFECTIVE_L1_TLB_SIZE(x) (((x) & 7) << 12) | ||
209 | #define EFFECTIVE_L1_TLB_SIZE_MASK 0x00007000 | ||
210 | #define EFFECTIVE_L1_TLB_SIZE_SHIFT 12 | ||
211 | #define EFFECTIVE_L1_QUEUE_SIZE(x) (((x) & 7) << 15) | ||
212 | #define EFFECTIVE_L1_QUEUE_SIZE_MASK 0x00038000 | ||
213 | #define EFFECTIVE_L1_QUEUE_SIZE_SHIFT 15 | ||
214 | #define MC_VM_L1_TLB_MCD_RD_B_CNTL 0x21A0 | ||
215 | #define MC_VM_L1_TLB_MCB_RD_GFX_CNTL 0x21FC | ||
216 | #define MC_VM_L1_TLB_MCB_RD_HDP_CNTL 0x2204 | ||
217 | #define MC_VM_L1_TLB_MCB_RD_PDMA_CNTL 0x2208 | ||
218 | #define MC_VM_L1_TLB_MCB_RD_SEM_CNTL 0x220C | ||
219 | #define MC_VM_L1_TLB_MCB_RD_SYS_CNTL 0x2200 | ||
220 | #define MC_VM_L1_TLB_MCD_WR_A_CNTL 0x21A4 | ||
221 | #define MC_VM_L1_TLB_MCD_WR_B_CNTL 0x21A8 | ||
222 | #define MC_VM_L1_TLB_MCB_WR_GFX_CNTL 0x2210 | ||
223 | #define MC_VM_L1_TLB_MCB_WR_HDP_CNTL 0x2218 | ||
224 | #define MC_VM_L1_TLB_MCB_WR_PDMA_CNTL 0x221C | ||
225 | #define MC_VM_L1_TLB_MCB_WR_SEM_CNTL 0x2220 | ||
226 | #define MC_VM_L1_TLB_MCB_WR_SYS_CNTL 0x2214 | ||
227 | #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 | ||
228 | #define LOGICAL_PAGE_NUMBER_MASK 0x000FFFFF | ||
229 | #define LOGICAL_PAGE_NUMBER_SHIFT 0 | ||
230 | #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 | ||
231 | #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 | ||
232 | |||
233 | #define PA_CL_ENHANCE 0x8A14 | ||
234 | #define CLIP_VTX_REORDER_ENA (1 << 0) | ||
235 | #define NUM_CLIP_SEQ(x) ((x) << 1) | ||
236 | #define PA_SC_AA_CONFIG 0x28C04 | ||
237 | #define PA_SC_AA_SAMPLE_LOCS_2S 0x8B40 | ||
238 | #define PA_SC_AA_SAMPLE_LOCS_4S 0x8B44 | ||
239 | #define PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8B48 | ||
240 | #define PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8B4C | ||
241 | #define S0_X(x) ((x) << 0) | ||
242 | #define S0_Y(x) ((x) << 4) | ||
243 | #define S1_X(x) ((x) << 8) | ||
244 | #define S1_Y(x) ((x) << 12) | ||
245 | #define S2_X(x) ((x) << 16) | ||
246 | #define S2_Y(x) ((x) << 20) | ||
247 | #define S3_X(x) ((x) << 24) | ||
248 | #define S3_Y(x) ((x) << 28) | ||
249 | #define S4_X(x) ((x) << 0) | ||
250 | #define S4_Y(x) ((x) << 4) | ||
251 | #define S5_X(x) ((x) << 8) | ||
252 | #define S5_Y(x) ((x) << 12) | ||
253 | #define S6_X(x) ((x) << 16) | ||
254 | #define S6_Y(x) ((x) << 20) | ||
255 | #define S7_X(x) ((x) << 24) | ||
256 | #define S7_Y(x) ((x) << 28) | ||
257 | #define PA_SC_CLIPRECT_RULE 0x2820c | ||
258 | #define PA_SC_ENHANCE 0x8BF0 | ||
259 | #define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) | ||
260 | #define FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) | ||
261 | #define PA_SC_LINE_STIPPLE 0x28A0C | ||
262 | #define PA_SC_LINE_STIPPLE_STATE 0x8B10 | ||
263 | #define PA_SC_MODE_CNTL 0x28A4C | ||
264 | #define PA_SC_MULTI_CHIP_CNTL 0x8B20 | ||
265 | |||
266 | #define PA_SC_SCREEN_SCISSOR_TL 0x28030 | ||
267 | #define PA_SC_GENERIC_SCISSOR_TL 0x28240 | ||
268 | #define PA_SC_WINDOW_SCISSOR_TL 0x28204 | ||
269 | |||
270 | #define PCIE_PORT_INDEX 0x0038 | ||
271 | #define PCIE_PORT_DATA 0x003C | ||
272 | |||
273 | #define RAMCFG 0x2408 | ||
274 | #define NOOFBANK_SHIFT 0 | ||
275 | #define NOOFBANK_MASK 0x00000001 | ||
276 | #define NOOFRANK_SHIFT 1 | ||
277 | #define NOOFRANK_MASK 0x00000002 | ||
278 | #define NOOFROWS_SHIFT 2 | ||
279 | #define NOOFROWS_MASK 0x0000001C | ||
280 | #define NOOFCOLS_SHIFT 5 | ||
281 | #define NOOFCOLS_MASK 0x00000060 | ||
282 | #define CHANSIZE_SHIFT 7 | ||
283 | #define CHANSIZE_MASK 0x00000080 | ||
284 | #define BURSTLENGTH_SHIFT 8 | ||
285 | #define BURSTLENGTH_MASK 0x00000100 | ||
286 | #define CHANSIZE_OVERRIDE (1 << 10) | ||
287 | |||
288 | #define SCRATCH_REG0 0x8500 | ||
289 | #define SCRATCH_REG1 0x8504 | ||
290 | #define SCRATCH_REG2 0x8508 | ||
291 | #define SCRATCH_REG3 0x850C | ||
292 | #define SCRATCH_REG4 0x8510 | ||
293 | #define SCRATCH_REG5 0x8514 | ||
294 | #define SCRATCH_REG6 0x8518 | ||
295 | #define SCRATCH_REG7 0x851C | ||
296 | #define SCRATCH_UMSK 0x8540 | ||
297 | #define SCRATCH_ADDR 0x8544 | ||
298 | |||
299 | #define SPI_CONFIG_CNTL 0x9100 | ||
300 | #define GPR_WRITE_PRIORITY(x) ((x) << 0) | ||
301 | #define DISABLE_INTERP_1 (1 << 5) | ||
302 | #define SPI_CONFIG_CNTL_1 0x913C | ||
303 | #define VTX_DONE_DELAY(x) ((x) << 0) | ||
304 | #define INTERP_ONE_PRIM_PER_ROW (1 << 4) | ||
305 | #define SPI_INPUT_Z 0x286D8 | ||
306 | #define SPI_PS_IN_CONTROL_0 0x286CC | ||
307 | #define NUM_INTERP(x) ((x)<<0) | ||
308 | #define POSITION_ENA (1<<8) | ||
309 | #define POSITION_CENTROID (1<<9) | ||
310 | #define POSITION_ADDR(x) ((x)<<10) | ||
311 | #define PARAM_GEN(x) ((x)<<15) | ||
312 | #define PARAM_GEN_ADDR(x) ((x)<<19) | ||
313 | #define BARYC_SAMPLE_CNTL(x) ((x)<<26) | ||
314 | #define PERSP_GRADIENT_ENA (1<<28) | ||
315 | #define LINEAR_GRADIENT_ENA (1<<29) | ||
316 | #define POSITION_SAMPLE (1<<30) | ||
317 | #define BARYC_AT_SAMPLE_ENA (1<<31) | ||
318 | #define SPI_PS_IN_CONTROL_1 0x286D0 | ||
319 | #define GEN_INDEX_PIX (1<<0) | ||
320 | #define GEN_INDEX_PIX_ADDR(x) ((x)<<1) | ||
321 | #define FRONT_FACE_ENA (1<<8) | ||
322 | #define FRONT_FACE_CHAN(x) ((x)<<9) | ||
323 | #define FRONT_FACE_ALL_BITS (1<<11) | ||
324 | #define FRONT_FACE_ADDR(x) ((x)<<12) | ||
325 | #define FOG_ADDR(x) ((x)<<17) | ||
326 | #define FIXED_PT_POSITION_ENA (1<<24) | ||
327 | #define FIXED_PT_POSITION_ADDR(x) ((x)<<25) | ||
328 | |||
329 | #define SQ_MS_FIFO_SIZES 0x8CF0 | ||
330 | #define CACHE_FIFO_SIZE(x) ((x) << 0) | ||
331 | #define FETCH_FIFO_HIWATER(x) ((x) << 8) | ||
332 | #define DONE_FIFO_HIWATER(x) ((x) << 16) | ||
333 | #define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) | ||
334 | #define SQ_PGM_START_ES 0x28880 | ||
335 | #define SQ_PGM_START_FS 0x28894 | ||
336 | #define SQ_PGM_START_GS 0x2886C | ||
337 | #define SQ_PGM_START_PS 0x28840 | ||
338 | #define SQ_PGM_RESOURCES_PS 0x28850 | ||
339 | #define SQ_PGM_EXPORTS_PS 0x28854 | ||
340 | #define SQ_PGM_CF_OFFSET_PS 0x288cc | ||
341 | #define SQ_PGM_START_VS 0x28858 | ||
342 | #define SQ_PGM_RESOURCES_VS 0x28868 | ||
343 | #define SQ_PGM_CF_OFFSET_VS 0x288d0 | ||
344 | #define SQ_VTX_CONSTANT_WORD6_0 0x38018 | ||
345 | #define S__SQ_VTX_CONSTANT_TYPE(x) (((x) & 3) << 30) | ||
346 | #define G__SQ_VTX_CONSTANT_TYPE(x) (((x) >> 30) & 3) | ||
347 | #define SQ_TEX_VTX_INVALID_TEXTURE 0x0 | ||
348 | #define SQ_TEX_VTX_INVALID_BUFFER 0x1 | ||
349 | #define SQ_TEX_VTX_VALID_TEXTURE 0x2 | ||
350 | #define SQ_TEX_VTX_VALID_BUFFER 0x3 | ||
351 | |||
352 | |||
353 | #define SX_MISC 0x28350 | ||
354 | #define SX_DEBUG_1 0x9054 | ||
355 | #define SMX_EVENT_RELEASE (1 << 0) | ||
356 | #define ENABLE_NEW_SMX_ADDRESS (1 << 16) | ||
357 | |||
358 | #define TA_CNTL_AUX 0x9508 | ||
359 | #define DISABLE_CUBE_WRAP (1 << 0) | ||
360 | #define DISABLE_CUBE_ANISO (1 << 1) | ||
361 | #define SYNC_GRADIENT (1 << 24) | ||
362 | #define SYNC_WALKER (1 << 25) | ||
363 | #define SYNC_ALIGNER (1 << 26) | ||
364 | #define BILINEAR_PRECISION_6_BIT (0 << 31) | ||
365 | #define BILINEAR_PRECISION_8_BIT (1 << 31) | ||
366 | |||
367 | #define TC_CNTL 0x9608 | ||
368 | #define TC_L2_SIZE(x) ((x)<<5) | ||
369 | #define L2_DISABLE_LATE_HIT (1<<9) | ||
370 | |||
371 | |||
372 | #define VGT_CACHE_INVALIDATION 0x88C4 | ||
373 | #define CACHE_INVALIDATION(x) ((x)<<0) | ||
374 | #define VC_ONLY 0 | ||
375 | #define TC_ONLY 1 | ||
376 | #define VC_AND_TC 2 | ||
377 | #define VGT_DMA_BASE 0x287E8 | ||
378 | #define VGT_DMA_BASE_HI 0x287E4 | ||
379 | #define VGT_ES_PER_GS 0x88CC | ||
380 | #define VGT_GS_PER_ES 0x88C8 | ||
381 | #define VGT_GS_PER_VS 0x88E8 | ||
382 | #define VGT_GS_VERTEX_REUSE 0x88D4 | ||
383 | #define VGT_PRIMITIVE_TYPE 0x8958 | ||
384 | #define VGT_NUM_INSTANCES 0x8974 | ||
385 | #define VGT_OUT_DEALLOC_CNTL 0x28C5C | ||
386 | #define DEALLOC_DIST_MASK 0x0000007F | ||
387 | #define VGT_STRMOUT_BASE_OFFSET_0 0x28B10 | ||
388 | #define VGT_STRMOUT_BASE_OFFSET_1 0x28B14 | ||
389 | #define VGT_STRMOUT_BASE_OFFSET_2 0x28B18 | ||
390 | #define VGT_STRMOUT_BASE_OFFSET_3 0x28B1c | ||
391 | #define VGT_STRMOUT_BASE_OFFSET_HI_0 0x28B44 | ||
392 | #define VGT_STRMOUT_BASE_OFFSET_HI_1 0x28B48 | ||
393 | #define VGT_STRMOUT_BASE_OFFSET_HI_2 0x28B4c | ||
394 | #define VGT_STRMOUT_BASE_OFFSET_HI_3 0x28B50 | ||
395 | #define VGT_STRMOUT_BUFFER_BASE_0 0x28AD8 | ||
396 | #define VGT_STRMOUT_BUFFER_BASE_1 0x28AE8 | ||
397 | #define VGT_STRMOUT_BUFFER_BASE_2 0x28AF8 | ||
398 | #define VGT_STRMOUT_BUFFER_BASE_3 0x28B08 | ||
399 | #define VGT_STRMOUT_BUFFER_OFFSET_0 0x28ADC | ||
400 | #define VGT_STRMOUT_BUFFER_OFFSET_1 0x28AEC | ||
401 | #define VGT_STRMOUT_BUFFER_OFFSET_2 0x28AFC | ||
402 | #define VGT_STRMOUT_BUFFER_OFFSET_3 0x28B0C | ||
403 | #define VGT_STRMOUT_EN 0x28AB0 | ||
404 | #define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 | ||
405 | #define VTX_REUSE_DEPTH_MASK 0x000000FF | ||
406 | #define VGT_EVENT_INITIATOR 0x28a90 | ||
407 | # define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) | ||
408 | |||
409 | #define VM_CONTEXT0_CNTL 0x1410 | ||
410 | #define ENABLE_CONTEXT (1 << 0) | ||
411 | #define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) | ||
412 | #define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) | ||
413 | #define VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 | ||
414 | #define VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14B0 | ||
415 | #define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 | ||
416 | #define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 | ||
417 | #define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15B4 | ||
418 | #define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1554 | ||
419 | #define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 | ||
420 | #define REQUEST_TYPE(x) (((x) & 0xf) << 0) | ||
421 | #define RESPONSE_TYPE_MASK 0x000000F0 | ||
422 | #define RESPONSE_TYPE_SHIFT 4 | ||
423 | #define VM_L2_CNTL 0x1400 | ||
424 | #define ENABLE_L2_CACHE (1 << 0) | ||
425 | #define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) | ||
426 | #define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) | ||
427 | #define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 13) | ||
428 | #define VM_L2_CNTL2 0x1404 | ||
429 | #define INVALIDATE_ALL_L1_TLBS (1 << 0) | ||
430 | #define INVALIDATE_L2_CACHE (1 << 1) | ||
431 | #define VM_L2_CNTL3 0x1408 | ||
432 | #define BANK_SELECT_0(x) (((x) & 0x1f) << 0) | ||
433 | #define BANK_SELECT_1(x) (((x) & 0x1f) << 5) | ||
434 | #define L2_CACHE_UPDATE_MODE(x) (((x) & 3) << 10) | ||
435 | #define VM_L2_STATUS 0x140C | ||
436 | #define L2_BUSY (1 << 0) | ||
437 | |||
438 | #define WAIT_UNTIL 0x8040 | ||
439 | #define WAIT_2D_IDLE_bit (1 << 14) | ||
440 | #define WAIT_3D_IDLE_bit (1 << 15) | ||
441 | #define WAIT_2D_IDLECLEAN_bit (1 << 16) | ||
442 | #define WAIT_3D_IDLECLEAN_bit (1 << 17) | ||
443 | |||
444 | |||
445 | |||
446 | /* | ||
447 | * PM4 | ||
448 | */ | ||
449 | #define PACKET_TYPE0 0 | ||
450 | #define PACKET_TYPE1 1 | ||
451 | #define PACKET_TYPE2 2 | ||
452 | #define PACKET_TYPE3 3 | ||
453 | |||
454 | #define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) | ||
455 | #define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) | ||
456 | #define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) | ||
457 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | ||
458 | #define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ | ||
459 | (((reg) >> 2) & 0xFFFF) | \ | ||
460 | ((n) & 0x3FFF) << 16) | ||
461 | #define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ | ||
462 | (((op) & 0xFF) << 8) | \ | ||
463 | ((n) & 0x3FFF) << 16) | ||
464 | |||
465 | /* Packet 3 types */ | ||
466 | #define PACKET3_NOP 0x10 | ||
467 | #define PACKET3_INDIRECT_BUFFER_END 0x17 | ||
468 | #define PACKET3_SET_PREDICATION 0x20 | ||
469 | #define PACKET3_REG_RMW 0x21 | ||
470 | #define PACKET3_COND_EXEC 0x22 | ||
471 | #define PACKET3_PRED_EXEC 0x23 | ||
472 | #define PACKET3_START_3D_CMDBUF 0x24 | ||
473 | #define PACKET3_DRAW_INDEX_2 0x27 | ||
474 | #define PACKET3_CONTEXT_CONTROL 0x28 | ||
475 | #define PACKET3_DRAW_INDEX_IMMD_BE 0x29 | ||
476 | #define PACKET3_INDEX_TYPE 0x2A | ||
477 | #define PACKET3_DRAW_INDEX 0x2B | ||
478 | #define PACKET3_DRAW_INDEX_AUTO 0x2D | ||
479 | #define PACKET3_DRAW_INDEX_IMMD 0x2E | ||
480 | #define PACKET3_NUM_INSTANCES 0x2F | ||
481 | #define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 | ||
482 | #define PACKET3_INDIRECT_BUFFER_MP 0x38 | ||
483 | #define PACKET3_MEM_SEMAPHORE 0x39 | ||
484 | #define PACKET3_MPEG_INDEX 0x3A | ||
485 | #define PACKET3_WAIT_REG_MEM 0x3C | ||
486 | #define PACKET3_MEM_WRITE 0x3D | ||
487 | #define PACKET3_INDIRECT_BUFFER 0x32 | ||
488 | #define PACKET3_CP_INTERRUPT 0x40 | ||
489 | #define PACKET3_SURFACE_SYNC 0x43 | ||
490 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | ||
491 | # define PACKET3_TC_ACTION_ENA (1 << 23) | ||
492 | # define PACKET3_VC_ACTION_ENA (1 << 24) | ||
493 | # define PACKET3_CB_ACTION_ENA (1 << 25) | ||
494 | # define PACKET3_DB_ACTION_ENA (1 << 26) | ||
495 | # define PACKET3_SH_ACTION_ENA (1 << 27) | ||
496 | # define PACKET3_SMX_ACTION_ENA (1 << 28) | ||
497 | #define PACKET3_ME_INITIALIZE 0x44 | ||
498 | #define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) | ||
499 | #define PACKET3_COND_WRITE 0x45 | ||
500 | #define PACKET3_EVENT_WRITE 0x46 | ||
501 | #define PACKET3_EVENT_WRITE_EOP 0x47 | ||
502 | #define PACKET3_ONE_REG_WRITE 0x57 | ||
503 | #define PACKET3_SET_CONFIG_REG 0x68 | ||
504 | #define PACKET3_SET_CONFIG_REG_OFFSET 0x00008000 | ||
505 | #define PACKET3_SET_CONFIG_REG_END 0x0000ac00 | ||
506 | #define PACKET3_SET_CONTEXT_REG 0x69 | ||
507 | #define PACKET3_SET_CONTEXT_REG_OFFSET 0x00028000 | ||
508 | #define PACKET3_SET_CONTEXT_REG_END 0x00029000 | ||
509 | #define PACKET3_SET_ALU_CONST 0x6A | ||
510 | #define PACKET3_SET_ALU_CONST_OFFSET 0x00030000 | ||
511 | #define PACKET3_SET_ALU_CONST_END 0x00032000 | ||
512 | #define PACKET3_SET_BOOL_CONST 0x6B | ||
513 | #define PACKET3_SET_BOOL_CONST_OFFSET 0x0003e380 | ||
514 | #define PACKET3_SET_BOOL_CONST_END 0x00040000 | ||
515 | #define PACKET3_SET_LOOP_CONST 0x6C | ||
516 | #define PACKET3_SET_LOOP_CONST_OFFSET 0x0003e200 | ||
517 | #define PACKET3_SET_LOOP_CONST_END 0x0003e380 | ||
518 | #define PACKET3_SET_RESOURCE 0x6D | ||
519 | #define PACKET3_SET_RESOURCE_OFFSET 0x00038000 | ||
520 | #define PACKET3_SET_RESOURCE_END 0x0003c000 | ||
521 | #define PACKET3_SET_SAMPLER 0x6E | ||
522 | #define PACKET3_SET_SAMPLER_OFFSET 0x0003c000 | ||
523 | #define PACKET3_SET_SAMPLER_END 0x0003cff0 | ||
524 | #define PACKET3_SET_CTL_CONST 0x6F | ||
525 | #define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 | ||
526 | #define PACKET3_SET_CTL_CONST_END 0x0003e200 | ||
527 | #define PACKET3_SURFACE_BASE_UPDATE 0x73 | ||
528 | |||
529 | |||
530 | #define R_008020_GRBM_SOFT_RESET 0x8020 | ||
531 | #define S_008020_SOFT_RESET_CP(x) (((x) & 1) << 0) | ||
532 | #define S_008020_SOFT_RESET_CB(x) (((x) & 1) << 1) | ||
533 | #define S_008020_SOFT_RESET_CR(x) (((x) & 1) << 2) | ||
534 | #define S_008020_SOFT_RESET_DB(x) (((x) & 1) << 3) | ||
535 | #define S_008020_SOFT_RESET_PA(x) (((x) & 1) << 5) | ||
536 | #define S_008020_SOFT_RESET_SC(x) (((x) & 1) << 6) | ||
537 | #define S_008020_SOFT_RESET_SMX(x) (((x) & 1) << 7) | ||
538 | #define S_008020_SOFT_RESET_SPI(x) (((x) & 1) << 8) | ||
539 | #define S_008020_SOFT_RESET_SH(x) (((x) & 1) << 9) | ||
540 | #define S_008020_SOFT_RESET_SX(x) (((x) & 1) << 10) | ||
541 | #define S_008020_SOFT_RESET_TC(x) (((x) & 1) << 11) | ||
542 | #define S_008020_SOFT_RESET_TA(x) (((x) & 1) << 12) | ||
543 | #define S_008020_SOFT_RESET_VC(x) (((x) & 1) << 13) | ||
544 | #define S_008020_SOFT_RESET_VGT(x) (((x) & 1) << 14) | ||
545 | #define R_008010_GRBM_STATUS 0x8010 | ||
546 | #define S_008010_CMDFIFO_AVAIL(x) (((x) & 0x1F) << 0) | ||
547 | #define S_008010_CP_RQ_PENDING(x) (((x) & 1) << 6) | ||
548 | #define S_008010_CF_RQ_PENDING(x) (((x) & 1) << 7) | ||
549 | #define S_008010_PF_RQ_PENDING(x) (((x) & 1) << 8) | ||
550 | #define S_008010_GRBM_EE_BUSY(x) (((x) & 1) << 10) | ||
551 | #define S_008010_VC_BUSY(x) (((x) & 1) << 11) | ||
552 | #define S_008010_DB03_CLEAN(x) (((x) & 1) << 12) | ||
553 | #define S_008010_CB03_CLEAN(x) (((x) & 1) << 13) | ||
554 | #define S_008010_VGT_BUSY_NO_DMA(x) (((x) & 1) << 16) | ||
555 | #define S_008010_VGT_BUSY(x) (((x) & 1) << 17) | ||
556 | #define S_008010_TA03_BUSY(x) (((x) & 1) << 18) | ||
557 | #define S_008010_TC_BUSY(x) (((x) & 1) << 19) | ||
558 | #define S_008010_SX_BUSY(x) (((x) & 1) << 20) | ||
559 | #define S_008010_SH_BUSY(x) (((x) & 1) << 21) | ||
560 | #define S_008010_SPI03_BUSY(x) (((x) & 1) << 22) | ||
561 | #define S_008010_SMX_BUSY(x) (((x) & 1) << 23) | ||
562 | #define S_008010_SC_BUSY(x) (((x) & 1) << 24) | ||
563 | #define S_008010_PA_BUSY(x) (((x) & 1) << 25) | ||
564 | #define S_008010_DB03_BUSY(x) (((x) & 1) << 26) | ||
565 | #define S_008010_CR_BUSY(x) (((x) & 1) << 27) | ||
566 | #define S_008010_CP_COHERENCY_BUSY(x) (((x) & 1) << 28) | ||
567 | #define S_008010_CP_BUSY(x) (((x) & 1) << 29) | ||
568 | #define S_008010_CB03_BUSY(x) (((x) & 1) << 30) | ||
569 | #define S_008010_GUI_ACTIVE(x) (((x) & 1) << 31) | ||
570 | #define G_008010_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x1F) | ||
571 | #define G_008010_CP_RQ_PENDING(x) (((x) >> 6) & 1) | ||
572 | #define G_008010_CF_RQ_PENDING(x) (((x) >> 7) & 1) | ||
573 | #define G_008010_PF_RQ_PENDING(x) (((x) >> 8) & 1) | ||
574 | #define G_008010_GRBM_EE_BUSY(x) (((x) >> 10) & 1) | ||
575 | #define G_008010_VC_BUSY(x) (((x) >> 11) & 1) | ||
576 | #define G_008010_DB03_CLEAN(x) (((x) >> 12) & 1) | ||
577 | #define G_008010_CB03_CLEAN(x) (((x) >> 13) & 1) | ||
578 | #define G_008010_VGT_BUSY_NO_DMA(x) (((x) >> 16) & 1) | ||
579 | #define G_008010_VGT_BUSY(x) (((x) >> 17) & 1) | ||
580 | #define G_008010_TA03_BUSY(x) (((x) >> 18) & 1) | ||
581 | #define G_008010_TC_BUSY(x) (((x) >> 19) & 1) | ||
582 | #define G_008010_SX_BUSY(x) (((x) >> 20) & 1) | ||
583 | #define G_008010_SH_BUSY(x) (((x) >> 21) & 1) | ||
584 | #define G_008010_SPI03_BUSY(x) (((x) >> 22) & 1) | ||
585 | #define G_008010_SMX_BUSY(x) (((x) >> 23) & 1) | ||
586 | #define G_008010_SC_BUSY(x) (((x) >> 24) & 1) | ||
587 | #define G_008010_PA_BUSY(x) (((x) >> 25) & 1) | ||
588 | #define G_008010_DB03_BUSY(x) (((x) >> 26) & 1) | ||
589 | #define G_008010_CR_BUSY(x) (((x) >> 27) & 1) | ||
590 | #define G_008010_CP_COHERENCY_BUSY(x) (((x) >> 28) & 1) | ||
591 | #define G_008010_CP_BUSY(x) (((x) >> 29) & 1) | ||
592 | #define G_008010_CB03_BUSY(x) (((x) >> 30) & 1) | ||
593 | #define G_008010_GUI_ACTIVE(x) (((x) >> 31) & 1) | ||
594 | #define R_008014_GRBM_STATUS2 0x8014 | ||
595 | #define S_008014_CR_CLEAN(x) (((x) & 1) << 0) | ||
596 | #define S_008014_SMX_CLEAN(x) (((x) & 1) << 1) | ||
597 | #define S_008014_SPI0_BUSY(x) (((x) & 1) << 8) | ||
598 | #define S_008014_SPI1_BUSY(x) (((x) & 1) << 9) | ||
599 | #define S_008014_SPI2_BUSY(x) (((x) & 1) << 10) | ||
600 | #define S_008014_SPI3_BUSY(x) (((x) & 1) << 11) | ||
601 | #define S_008014_TA0_BUSY(x) (((x) & 1) << 12) | ||
602 | #define S_008014_TA1_BUSY(x) (((x) & 1) << 13) | ||
603 | #define S_008014_TA2_BUSY(x) (((x) & 1) << 14) | ||
604 | #define S_008014_TA3_BUSY(x) (((x) & 1) << 15) | ||
605 | #define S_008014_DB0_BUSY(x) (((x) & 1) << 16) | ||
606 | #define S_008014_DB1_BUSY(x) (((x) & 1) << 17) | ||
607 | #define S_008014_DB2_BUSY(x) (((x) & 1) << 18) | ||
608 | #define S_008014_DB3_BUSY(x) (((x) & 1) << 19) | ||
609 | #define S_008014_CB0_BUSY(x) (((x) & 1) << 20) | ||
610 | #define S_008014_CB1_BUSY(x) (((x) & 1) << 21) | ||
611 | #define S_008014_CB2_BUSY(x) (((x) & 1) << 22) | ||
612 | #define S_008014_CB3_BUSY(x) (((x) & 1) << 23) | ||
613 | #define G_008014_CR_CLEAN(x) (((x) >> 0) & 1) | ||
614 | #define G_008014_SMX_CLEAN(x) (((x) >> 1) & 1) | ||
615 | #define G_008014_SPI0_BUSY(x) (((x) >> 8) & 1) | ||
616 | #define G_008014_SPI1_BUSY(x) (((x) >> 9) & 1) | ||
617 | #define G_008014_SPI2_BUSY(x) (((x) >> 10) & 1) | ||
618 | #define G_008014_SPI3_BUSY(x) (((x) >> 11) & 1) | ||
619 | #define G_008014_TA0_BUSY(x) (((x) >> 12) & 1) | ||
620 | #define G_008014_TA1_BUSY(x) (((x) >> 13) & 1) | ||
621 | #define G_008014_TA2_BUSY(x) (((x) >> 14) & 1) | ||
622 | #define G_008014_TA3_BUSY(x) (((x) >> 15) & 1) | ||
623 | #define G_008014_DB0_BUSY(x) (((x) >> 16) & 1) | ||
624 | #define G_008014_DB1_BUSY(x) (((x) >> 17) & 1) | ||
625 | #define G_008014_DB2_BUSY(x) (((x) >> 18) & 1) | ||
626 | #define G_008014_DB3_BUSY(x) (((x) >> 19) & 1) | ||
627 | #define G_008014_CB0_BUSY(x) (((x) >> 20) & 1) | ||
628 | #define G_008014_CB1_BUSY(x) (((x) >> 21) & 1) | ||
629 | #define G_008014_CB2_BUSY(x) (((x) >> 22) & 1) | ||
630 | #define G_008014_CB3_BUSY(x) (((x) >> 23) & 1) | ||
631 | #define R_000E50_SRBM_STATUS 0x0E50 | ||
632 | #define G_000E50_RLC_RQ_PENDING(x) (((x) >> 3) & 1) | ||
633 | #define G_000E50_RCU_RQ_PENDING(x) (((x) >> 4) & 1) | ||
634 | #define G_000E50_GRBM_RQ_PENDING(x) (((x) >> 5) & 1) | ||
635 | #define G_000E50_HI_RQ_PENDING(x) (((x) >> 6) & 1) | ||
636 | #define G_000E50_IO_EXTERN_SIGNAL(x) (((x) >> 7) & 1) | ||
637 | #define G_000E50_VMC_BUSY(x) (((x) >> 8) & 1) | ||
638 | #define G_000E50_MCB_BUSY(x) (((x) >> 9) & 1) | ||
639 | #define G_000E50_MCDZ_BUSY(x) (((x) >> 10) & 1) | ||
640 | #define G_000E50_MCDY_BUSY(x) (((x) >> 11) & 1) | ||
641 | #define G_000E50_MCDX_BUSY(x) (((x) >> 12) & 1) | ||
642 | #define G_000E50_MCDW_BUSY(x) (((x) >> 13) & 1) | ||
643 | #define G_000E50_SEM_BUSY(x) (((x) >> 14) & 1) | ||
644 | #define G_000E50_RLC_BUSY(x) (((x) >> 15) & 1) | ||
645 | #define R_000E60_SRBM_SOFT_RESET 0x0E60 | ||
646 | #define S_000E60_SOFT_RESET_BIF(x) (((x) & 1) << 1) | ||
647 | #define S_000E60_SOFT_RESET_CG(x) (((x) & 1) << 2) | ||
648 | #define S_000E60_SOFT_RESET_CMC(x) (((x) & 1) << 3) | ||
649 | #define S_000E60_SOFT_RESET_CSC(x) (((x) & 1) << 4) | ||
650 | #define S_000E60_SOFT_RESET_DC(x) (((x) & 1) << 5) | ||
651 | #define S_000E60_SOFT_RESET_GRBM(x) (((x) & 1) << 8) | ||
652 | #define S_000E60_SOFT_RESET_HDP(x) (((x) & 1) << 9) | ||
653 | #define S_000E60_SOFT_RESET_IH(x) (((x) & 1) << 10) | ||
654 | #define S_000E60_SOFT_RESET_MC(x) (((x) & 1) << 11) | ||
655 | #define S_000E60_SOFT_RESET_RLC(x) (((x) & 1) << 13) | ||
656 | #define S_000E60_SOFT_RESET_ROM(x) (((x) & 1) << 14) | ||
657 | #define S_000E60_SOFT_RESET_SEM(x) (((x) & 1) << 15) | ||
658 | #define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16) | ||
659 | #define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) | ||
660 | |||
661 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e47f2fc294ce..3299733ac300 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -50,8 +50,8 @@ | |||
50 | #include <linux/kref.h> | 50 | #include <linux/kref.h> |
51 | 51 | ||
52 | #include "radeon_mode.h" | 52 | #include "radeon_mode.h" |
53 | #include "radeon_share.h" | ||
53 | #include "radeon_reg.h" | 54 | #include "radeon_reg.h" |
54 | #include "r300.h" | ||
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Modules parameters. | 57 | * Modules parameters. |
@@ -112,10 +112,11 @@ enum radeon_family { | |||
112 | CHIP_RV635, | 112 | CHIP_RV635, |
113 | CHIP_RV670, | 113 | CHIP_RV670, |
114 | CHIP_RS780, | 114 | CHIP_RS780, |
115 | CHIP_RS880, | ||
115 | CHIP_RV770, | 116 | CHIP_RV770, |
116 | CHIP_RV730, | 117 | CHIP_RV730, |
117 | CHIP_RV710, | 118 | CHIP_RV710, |
118 | CHIP_RS880, | 119 | CHIP_RV740, |
119 | CHIP_LAST, | 120 | CHIP_LAST, |
120 | }; | 121 | }; |
121 | 122 | ||
@@ -152,10 +153,21 @@ struct radeon_device; | |||
152 | */ | 153 | */ |
153 | bool radeon_get_bios(struct radeon_device *rdev); | 154 | bool radeon_get_bios(struct radeon_device *rdev); |
154 | 155 | ||
156 | |||
155 | /* | 157 | /* |
156 | * Clocks | 158 | * Dummy page |
157 | */ | 159 | */ |
160 | struct radeon_dummy_page { | ||
161 | struct page *page; | ||
162 | dma_addr_t addr; | ||
163 | }; | ||
164 | int radeon_dummy_page_init(struct radeon_device *rdev); | ||
165 | void radeon_dummy_page_fini(struct radeon_device *rdev); | ||
166 | |||
158 | 167 | ||
168 | /* | ||
169 | * Clocks | ||
170 | */ | ||
159 | struct radeon_clock { | 171 | struct radeon_clock { |
160 | struct radeon_pll p1pll; | 172 | struct radeon_pll p1pll; |
161 | struct radeon_pll p2pll; | 173 | struct radeon_pll p2pll; |
@@ -166,6 +178,7 @@ struct radeon_clock { | |||
166 | uint32_t default_sclk; | 178 | uint32_t default_sclk; |
167 | }; | 179 | }; |
168 | 180 | ||
181 | |||
169 | /* | 182 | /* |
170 | * Fences. | 183 | * Fences. |
171 | */ | 184 | */ |
@@ -332,14 +345,18 @@ struct radeon_mc { | |||
332 | resource_size_t aper_size; | 345 | resource_size_t aper_size; |
333 | resource_size_t aper_base; | 346 | resource_size_t aper_base; |
334 | resource_size_t agp_base; | 347 | resource_size_t agp_base; |
335 | unsigned gtt_location; | ||
336 | unsigned gtt_size; | ||
337 | unsigned vram_location; | ||
338 | /* for some chips with <= 32MB we need to lie | 348 | /* for some chips with <= 32MB we need to lie |
339 | * about vram size near mc fb location */ | 349 | * about vram size near mc fb location */ |
340 | unsigned mc_vram_size; | 350 | u64 mc_vram_size; |
351 | u64 gtt_location; | ||
352 | u64 gtt_size; | ||
353 | u64 gtt_start; | ||
354 | u64 gtt_end; | ||
355 | u64 vram_location; | ||
356 | u64 vram_start; | ||
357 | u64 vram_end; | ||
341 | unsigned vram_width; | 358 | unsigned vram_width; |
342 | unsigned real_vram_size; | 359 | u64 real_vram_size; |
343 | int vram_mtrr; | 360 | int vram_mtrr; |
344 | bool vram_is_ddr; | 361 | bool vram_is_ddr; |
345 | }; | 362 | }; |
@@ -411,6 +428,16 @@ struct radeon_cp { | |||
411 | bool ready; | 428 | bool ready; |
412 | }; | 429 | }; |
413 | 430 | ||
431 | struct r600_blit { | ||
432 | struct radeon_object *shader_obj; | ||
433 | u64 shader_gpu_addr; | ||
434 | u32 vs_offset, ps_offset; | ||
435 | u32 state_offset; | ||
436 | u32 state_len; | ||
437 | u32 vb_used, vb_total; | ||
438 | struct radeon_ib *vb_ib; | ||
439 | }; | ||
440 | |||
414 | int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib); | 441 | int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib); |
415 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); | 442 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); |
416 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); | 443 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); |
@@ -463,6 +490,7 @@ struct radeon_cs_parser { | |||
463 | int chunk_relocs_idx; | 490 | int chunk_relocs_idx; |
464 | struct radeon_ib *ib; | 491 | struct radeon_ib *ib; |
465 | void *track; | 492 | void *track; |
493 | unsigned family; | ||
466 | }; | 494 | }; |
467 | 495 | ||
468 | struct radeon_cs_packet { | 496 | struct radeon_cs_packet { |
@@ -559,6 +587,9 @@ int r100_debugfs_cp_init(struct radeon_device *rdev); | |||
559 | */ | 587 | */ |
560 | struct radeon_asic { | 588 | struct radeon_asic { |
561 | int (*init)(struct radeon_device *rdev); | 589 | int (*init)(struct radeon_device *rdev); |
590 | void (*fini)(struct radeon_device *rdev); | ||
591 | int (*resume)(struct radeon_device *rdev); | ||
592 | int (*suspend)(struct radeon_device *rdev); | ||
562 | void (*errata)(struct radeon_device *rdev); | 593 | void (*errata)(struct radeon_device *rdev); |
563 | void (*vram_info)(struct radeon_device *rdev); | 594 | void (*vram_info)(struct radeon_device *rdev); |
564 | int (*gpu_reset)(struct radeon_device *rdev); | 595 | int (*gpu_reset)(struct radeon_device *rdev); |
@@ -573,7 +604,11 @@ struct radeon_asic { | |||
573 | int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); | 604 | int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); |
574 | void (*cp_fini)(struct radeon_device *rdev); | 605 | void (*cp_fini)(struct radeon_device *rdev); |
575 | void (*cp_disable)(struct radeon_device *rdev); | 606 | void (*cp_disable)(struct radeon_device *rdev); |
607 | void (*cp_commit)(struct radeon_device *rdev); | ||
576 | void (*ring_start)(struct radeon_device *rdev); | 608 | void (*ring_start)(struct radeon_device *rdev); |
609 | int (*ring_test)(struct radeon_device *rdev); | ||
610 | void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); | ||
611 | int (*ib_test)(struct radeon_device *rdev); | ||
577 | int (*irq_set)(struct radeon_device *rdev); | 612 | int (*irq_set)(struct radeon_device *rdev); |
578 | int (*irq_process)(struct radeon_device *rdev); | 613 | int (*irq_process)(struct radeon_device *rdev); |
579 | u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); | 614 | u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); |
@@ -613,6 +648,8 @@ struct r100_asic { | |||
613 | union radeon_asic_config { | 648 | union radeon_asic_config { |
614 | struct r300_asic r300; | 649 | struct r300_asic r300; |
615 | struct r100_asic r100; | 650 | struct r100_asic r100; |
651 | struct r600_asic r600; | ||
652 | struct rv770_asic rv770; | ||
616 | }; | 653 | }; |
617 | 654 | ||
618 | 655 | ||
@@ -698,12 +735,16 @@ struct radeon_device { | |||
698 | struct radeon_pm pm; | 735 | struct radeon_pm pm; |
699 | struct mutex cs_mutex; | 736 | struct mutex cs_mutex; |
700 | struct radeon_wb wb; | 737 | struct radeon_wb wb; |
738 | struct radeon_dummy_page dummy_page; | ||
701 | bool gpu_lockup; | 739 | bool gpu_lockup; |
702 | bool shutdown; | 740 | bool shutdown; |
703 | bool suspend; | 741 | bool suspend; |
704 | bool need_dma32; | 742 | bool need_dma32; |
743 | bool new_init_path; | ||
705 | struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; | 744 | struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; |
706 | const struct firmware *fw; /* firmware */ | 745 | const struct firmware *me_fw; /* all family ME firmware */ |
746 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | ||
747 | struct r600_blit r600_blit; | ||
707 | }; | 748 | }; |
708 | 749 | ||
709 | int radeon_device_init(struct radeon_device *rdev, | 750 | int radeon_device_init(struct radeon_device *rdev, |
@@ -713,6 +754,13 @@ int radeon_device_init(struct radeon_device *rdev, | |||
713 | void radeon_device_fini(struct radeon_device *rdev); | 754 | void radeon_device_fini(struct radeon_device *rdev); |
714 | int radeon_gpu_wait_for_idle(struct radeon_device *rdev); | 755 | int radeon_gpu_wait_for_idle(struct radeon_device *rdev); |
715 | 756 | ||
757 | /* r600 blit */ | ||
758 | int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes); | ||
759 | void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence); | ||
760 | void r600_kms_blit_copy(struct radeon_device *rdev, | ||
761 | u64 src_gpu_addr, u64 dst_gpu_addr, | ||
762 | int size_bytes); | ||
763 | |||
716 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) | 764 | static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) |
717 | { | 765 | { |
718 | if (reg < 0x10000) | 766 | if (reg < 0x10000) |
@@ -740,6 +788,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
740 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) | 788 | #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) |
741 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) | 789 | #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) |
742 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) | 790 | #define RREG32(reg) r100_mm_rreg(rdev, (reg)) |
791 | #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) | ||
743 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) | 792 | #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) |
744 | #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) | 793 | #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
745 | #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) | 794 | #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) |
@@ -763,6 +812,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
763 | tmp_ |= ((val) & ~(mask)); \ | 812 | tmp_ |= ((val) & ~(mask)); \ |
764 | WREG32_PLL(reg, tmp_); \ | 813 | WREG32_PLL(reg, tmp_); \ |
765 | } while (0) | 814 | } while (0) |
815 | #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) | ||
766 | 816 | ||
767 | /* | 817 | /* |
768 | * Indirect registers accessor | 818 | * Indirect registers accessor |
@@ -827,51 +877,6 @@ void radeon_atombios_fini(struct radeon_device *rdev); | |||
827 | /* | 877 | /* |
828 | * RING helpers. | 878 | * RING helpers. |
829 | */ | 879 | */ |
830 | #define CP_PACKET0 0x00000000 | ||
831 | #define PACKET0_BASE_INDEX_SHIFT 0 | ||
832 | #define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) | ||
833 | #define PACKET0_COUNT_SHIFT 16 | ||
834 | #define PACKET0_COUNT_MASK (0x3fff << 16) | ||
835 | #define CP_PACKET1 0x40000000 | ||
836 | #define CP_PACKET2 0x80000000 | ||
837 | #define PACKET2_PAD_SHIFT 0 | ||
838 | #define PACKET2_PAD_MASK (0x3fffffff << 0) | ||
839 | #define CP_PACKET3 0xC0000000 | ||
840 | #define PACKET3_IT_OPCODE_SHIFT 8 | ||
841 | #define PACKET3_IT_OPCODE_MASK (0xff << 8) | ||
842 | #define PACKET3_COUNT_SHIFT 16 | ||
843 | #define PACKET3_COUNT_MASK (0x3fff << 16) | ||
844 | /* PACKET3 op code */ | ||
845 | #define PACKET3_NOP 0x10 | ||
846 | #define PACKET3_3D_DRAW_VBUF 0x28 | ||
847 | #define PACKET3_3D_DRAW_IMMD 0x29 | ||
848 | #define PACKET3_3D_DRAW_INDX 0x2A | ||
849 | #define PACKET3_3D_LOAD_VBPNTR 0x2F | ||
850 | #define PACKET3_INDX_BUFFER 0x33 | ||
851 | #define PACKET3_3D_DRAW_VBUF_2 0x34 | ||
852 | #define PACKET3_3D_DRAW_IMMD_2 0x35 | ||
853 | #define PACKET3_3D_DRAW_INDX_2 0x36 | ||
854 | #define PACKET3_BITBLT_MULTI 0x9B | ||
855 | |||
856 | #define PACKET0(reg, n) (CP_PACKET0 | \ | ||
857 | REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ | ||
858 | REG_SET(PACKET0_COUNT, (n))) | ||
859 | #define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) | ||
860 | #define PACKET3(op, n) (CP_PACKET3 | \ | ||
861 | REG_SET(PACKET3_IT_OPCODE, (op)) | \ | ||
862 | REG_SET(PACKET3_COUNT, (n))) | ||
863 | |||
864 | #define PACKET_TYPE0 0 | ||
865 | #define PACKET_TYPE1 1 | ||
866 | #define PACKET_TYPE2 2 | ||
867 | #define PACKET_TYPE3 3 | ||
868 | |||
869 | #define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) | ||
870 | #define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) | ||
871 | #define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) | ||
872 | #define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) | ||
873 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | ||
874 | |||
875 | static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | 880 | static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) |
876 | { | 881 | { |
877 | #if DRM_DEBUG_CODE | 882 | #if DRM_DEBUG_CODE |
@@ -890,6 +895,9 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
890 | * ASICs macro. | 895 | * ASICs macro. |
891 | */ | 896 | */ |
892 | #define radeon_init(rdev) (rdev)->asic->init((rdev)) | 897 | #define radeon_init(rdev) (rdev)->asic->init((rdev)) |
898 | #define radeon_fini(rdev) (rdev)->asic->fini((rdev)) | ||
899 | #define radeon_resume(rdev) (rdev)->asic->resume((rdev)) | ||
900 | #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) | ||
893 | #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) | 901 | #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) |
894 | #define radeon_errata(rdev) (rdev)->asic->errata((rdev)) | 902 | #define radeon_errata(rdev) (rdev)->asic->errata((rdev)) |
895 | #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) | 903 | #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) |
@@ -905,7 +913,11 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
905 | #define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize)) | 913 | #define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize)) |
906 | #define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev)) | 914 | #define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev)) |
907 | #define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev)) | 915 | #define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev)) |
916 | #define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev)) | ||
908 | #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) | 917 | #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) |
918 | #define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev)) | ||
919 | #define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib)) | ||
920 | #define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev)) | ||
909 | #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) | 921 | #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) |
910 | #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) | 922 | #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) |
911 | #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) | 923 | #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c9cbd8ae1f95..e87bb915a6de 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -60,6 +60,7 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | |||
60 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); | 60 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); |
61 | void r100_cp_fini(struct radeon_device *rdev); | 61 | void r100_cp_fini(struct radeon_device *rdev); |
62 | void r100_cp_disable(struct radeon_device *rdev); | 62 | void r100_cp_disable(struct radeon_device *rdev); |
63 | void r100_cp_commit(struct radeon_device *rdev); | ||
63 | void r100_ring_start(struct radeon_device *rdev); | 64 | void r100_ring_start(struct radeon_device *rdev); |
64 | int r100_irq_set(struct radeon_device *rdev); | 65 | int r100_irq_set(struct radeon_device *rdev); |
65 | int r100_irq_process(struct radeon_device *rdev); | 66 | int r100_irq_process(struct radeon_device *rdev); |
@@ -78,6 +79,9 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, | |||
78 | uint32_t offset, uint32_t obj_size); | 79 | uint32_t offset, uint32_t obj_size); |
79 | int r100_clear_surface_reg(struct radeon_device *rdev, int reg); | 80 | int r100_clear_surface_reg(struct radeon_device *rdev, int reg); |
80 | void r100_bandwidth_update(struct radeon_device *rdev); | 81 | void r100_bandwidth_update(struct radeon_device *rdev); |
82 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | ||
83 | int r100_ib_test(struct radeon_device *rdev); | ||
84 | int r100_ring_test(struct radeon_device *rdev); | ||
81 | 85 | ||
82 | static struct radeon_asic r100_asic = { | 86 | static struct radeon_asic r100_asic = { |
83 | .init = &r100_init, | 87 | .init = &r100_init, |
@@ -95,7 +99,11 @@ static struct radeon_asic r100_asic = { | |||
95 | .cp_init = &r100_cp_init, | 99 | .cp_init = &r100_cp_init, |
96 | .cp_fini = &r100_cp_fini, | 100 | .cp_fini = &r100_cp_fini, |
97 | .cp_disable = &r100_cp_disable, | 101 | .cp_disable = &r100_cp_disable, |
102 | .cp_commit = &r100_cp_commit, | ||
98 | .ring_start = &r100_ring_start, | 103 | .ring_start = &r100_ring_start, |
104 | .ring_test = &r100_ring_test, | ||
105 | .ring_ib_execute = &r100_ring_ib_execute, | ||
106 | .ib_test = &r100_ib_test, | ||
99 | .irq_set = &r100_irq_set, | 107 | .irq_set = &r100_irq_set, |
100 | .irq_process = &r100_irq_process, | 108 | .irq_process = &r100_irq_process, |
101 | .get_vblank_counter = &r100_get_vblank_counter, | 109 | .get_vblank_counter = &r100_get_vblank_counter, |
@@ -156,7 +164,11 @@ static struct radeon_asic r300_asic = { | |||
156 | .cp_init = &r100_cp_init, | 164 | .cp_init = &r100_cp_init, |
157 | .cp_fini = &r100_cp_fini, | 165 | .cp_fini = &r100_cp_fini, |
158 | .cp_disable = &r100_cp_disable, | 166 | .cp_disable = &r100_cp_disable, |
167 | .cp_commit = &r100_cp_commit, | ||
159 | .ring_start = &r300_ring_start, | 168 | .ring_start = &r300_ring_start, |
169 | .ring_test = &r100_ring_test, | ||
170 | .ring_ib_execute = &r100_ring_ib_execute, | ||
171 | .ib_test = &r100_ib_test, | ||
160 | .irq_set = &r100_irq_set, | 172 | .irq_set = &r100_irq_set, |
161 | .irq_process = &r100_irq_process, | 173 | .irq_process = &r100_irq_process, |
162 | .get_vblank_counter = &r100_get_vblank_counter, | 174 | .get_vblank_counter = &r100_get_vblank_counter, |
@@ -197,7 +209,11 @@ static struct radeon_asic r420_asic = { | |||
197 | .cp_init = &r100_cp_init, | 209 | .cp_init = &r100_cp_init, |
198 | .cp_fini = &r100_cp_fini, | 210 | .cp_fini = &r100_cp_fini, |
199 | .cp_disable = &r100_cp_disable, | 211 | .cp_disable = &r100_cp_disable, |
212 | .cp_commit = &r100_cp_commit, | ||
200 | .ring_start = &r300_ring_start, | 213 | .ring_start = &r300_ring_start, |
214 | .ring_test = &r100_ring_test, | ||
215 | .ring_ib_execute = &r100_ring_ib_execute, | ||
216 | .ib_test = &r100_ib_test, | ||
201 | .irq_set = &r100_irq_set, | 217 | .irq_set = &r100_irq_set, |
202 | .irq_process = &r100_irq_process, | 218 | .irq_process = &r100_irq_process, |
203 | .get_vblank_counter = &r100_get_vblank_counter, | 219 | .get_vblank_counter = &r100_get_vblank_counter, |
@@ -245,7 +261,11 @@ static struct radeon_asic rs400_asic = { | |||
245 | .cp_init = &r100_cp_init, | 261 | .cp_init = &r100_cp_init, |
246 | .cp_fini = &r100_cp_fini, | 262 | .cp_fini = &r100_cp_fini, |
247 | .cp_disable = &r100_cp_disable, | 263 | .cp_disable = &r100_cp_disable, |
264 | .cp_commit = &r100_cp_commit, | ||
248 | .ring_start = &r300_ring_start, | 265 | .ring_start = &r300_ring_start, |
266 | .ring_test = &r100_ring_test, | ||
267 | .ring_ib_execute = &r100_ring_ib_execute, | ||
268 | .ib_test = &r100_ib_test, | ||
249 | .irq_set = &r100_irq_set, | 269 | .irq_set = &r100_irq_set, |
250 | .irq_process = &r100_irq_process, | 270 | .irq_process = &r100_irq_process, |
251 | .get_vblank_counter = &r100_get_vblank_counter, | 271 | .get_vblank_counter = &r100_get_vblank_counter, |
@@ -298,7 +318,11 @@ static struct radeon_asic rs600_asic = { | |||
298 | .cp_init = &r100_cp_init, | 318 | .cp_init = &r100_cp_init, |
299 | .cp_fini = &r100_cp_fini, | 319 | .cp_fini = &r100_cp_fini, |
300 | .cp_disable = &r100_cp_disable, | 320 | .cp_disable = &r100_cp_disable, |
321 | .cp_commit = &r100_cp_commit, | ||
301 | .ring_start = &r300_ring_start, | 322 | .ring_start = &r300_ring_start, |
323 | .ring_test = &r100_ring_test, | ||
324 | .ring_ib_execute = &r100_ring_ib_execute, | ||
325 | .ib_test = &r100_ib_test, | ||
302 | .irq_set = &rs600_irq_set, | 326 | .irq_set = &rs600_irq_set, |
303 | .irq_process = &rs600_irq_process, | 327 | .irq_process = &rs600_irq_process, |
304 | .get_vblank_counter = &rs600_get_vblank_counter, | 328 | .get_vblank_counter = &rs600_get_vblank_counter, |
@@ -341,7 +365,11 @@ static struct radeon_asic rs690_asic = { | |||
341 | .cp_init = &r100_cp_init, | 365 | .cp_init = &r100_cp_init, |
342 | .cp_fini = &r100_cp_fini, | 366 | .cp_fini = &r100_cp_fini, |
343 | .cp_disable = &r100_cp_disable, | 367 | .cp_disable = &r100_cp_disable, |
368 | .cp_commit = &r100_cp_commit, | ||
344 | .ring_start = &r300_ring_start, | 369 | .ring_start = &r300_ring_start, |
370 | .ring_test = &r100_ring_test, | ||
371 | .ring_ib_execute = &r100_ring_ib_execute, | ||
372 | .ib_test = &r100_ib_test, | ||
345 | .irq_set = &rs600_irq_set, | 373 | .irq_set = &rs600_irq_set, |
346 | .irq_process = &rs600_irq_process, | 374 | .irq_process = &rs600_irq_process, |
347 | .get_vblank_counter = &rs600_get_vblank_counter, | 375 | .get_vblank_counter = &rs600_get_vblank_counter, |
@@ -391,7 +419,11 @@ static struct radeon_asic rv515_asic = { | |||
391 | .cp_init = &r100_cp_init, | 419 | .cp_init = &r100_cp_init, |
392 | .cp_fini = &r100_cp_fini, | 420 | .cp_fini = &r100_cp_fini, |
393 | .cp_disable = &r100_cp_disable, | 421 | .cp_disable = &r100_cp_disable, |
422 | .cp_commit = &r100_cp_commit, | ||
394 | .ring_start = &rv515_ring_start, | 423 | .ring_start = &rv515_ring_start, |
424 | .ring_test = &r100_ring_test, | ||
425 | .ring_ib_execute = &r100_ring_ib_execute, | ||
426 | .ib_test = &r100_ib_test, | ||
395 | .irq_set = &rs600_irq_set, | 427 | .irq_set = &rs600_irq_set, |
396 | .irq_process = &rs600_irq_process, | 428 | .irq_process = &rs600_irq_process, |
397 | .get_vblank_counter = &rs600_get_vblank_counter, | 429 | .get_vblank_counter = &rs600_get_vblank_counter, |
@@ -434,7 +466,11 @@ static struct radeon_asic r520_asic = { | |||
434 | .cp_init = &r100_cp_init, | 466 | .cp_init = &r100_cp_init, |
435 | .cp_fini = &r100_cp_fini, | 467 | .cp_fini = &r100_cp_fini, |
436 | .cp_disable = &r100_cp_disable, | 468 | .cp_disable = &r100_cp_disable, |
469 | .cp_commit = &r100_cp_commit, | ||
437 | .ring_start = &rv515_ring_start, | 470 | .ring_start = &rv515_ring_start, |
471 | .ring_test = &r100_ring_test, | ||
472 | .ring_ib_execute = &r100_ring_ib_execute, | ||
473 | .ib_test = &r100_ib_test, | ||
438 | .irq_set = &rs600_irq_set, | 474 | .irq_set = &rs600_irq_set, |
439 | .irq_process = &rs600_irq_process, | 475 | .irq_process = &rs600_irq_process, |
440 | .get_vblank_counter = &rs600_get_vblank_counter, | 476 | .get_vblank_counter = &rs600_get_vblank_counter, |
@@ -453,9 +489,127 @@ static struct radeon_asic r520_asic = { | |||
453 | }; | 489 | }; |
454 | 490 | ||
455 | /* | 491 | /* |
456 | * r600,rv610,rv630,rv620,rv635,rv670,rs780,rv770,rv730,rv710 | 492 | * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880 |
457 | */ | 493 | */ |
494 | int r600_init(struct radeon_device *rdev); | ||
495 | void r600_fini(struct radeon_device *rdev); | ||
496 | int r600_suspend(struct radeon_device *rdev); | ||
497 | int r600_resume(struct radeon_device *rdev); | ||
498 | int r600_wb_init(struct radeon_device *rdev); | ||
499 | void r600_wb_fini(struct radeon_device *rdev); | ||
500 | void r600_cp_commit(struct radeon_device *rdev); | ||
501 | void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); | ||
458 | uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg); | 502 | uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg); |
459 | void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 503 | void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
504 | int r600_cs_parse(struct radeon_cs_parser *p); | ||
505 | void r600_fence_ring_emit(struct radeon_device *rdev, | ||
506 | struct radeon_fence *fence); | ||
507 | int r600_copy_dma(struct radeon_device *rdev, | ||
508 | uint64_t src_offset, | ||
509 | uint64_t dst_offset, | ||
510 | unsigned num_pages, | ||
511 | struct radeon_fence *fence); | ||
512 | int r600_irq_process(struct radeon_device *rdev); | ||
513 | int r600_irq_set(struct radeon_device *rdev); | ||
514 | int r600_gpu_reset(struct radeon_device *rdev); | ||
515 | int r600_set_surface_reg(struct radeon_device *rdev, int reg, | ||
516 | uint32_t tiling_flags, uint32_t pitch, | ||
517 | uint32_t offset, uint32_t obj_size); | ||
518 | int r600_clear_surface_reg(struct radeon_device *rdev, int reg); | ||
519 | void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); | ||
520 | int r600_ib_test(struct radeon_device *rdev); | ||
521 | int r600_ring_test(struct radeon_device *rdev); | ||
522 | int r600_copy_blit(struct radeon_device *rdev, | ||
523 | uint64_t src_offset, uint64_t dst_offset, | ||
524 | unsigned num_pages, struct radeon_fence *fence); | ||
525 | |||
526 | static struct radeon_asic r600_asic = { | ||
527 | .errata = NULL, | ||
528 | .init = &r600_init, | ||
529 | .fini = &r600_fini, | ||
530 | .suspend = &r600_suspend, | ||
531 | .resume = &r600_resume, | ||
532 | .cp_commit = &r600_cp_commit, | ||
533 | .vram_info = NULL, | ||
534 | .gpu_reset = &r600_gpu_reset, | ||
535 | .mc_init = NULL, | ||
536 | .mc_fini = NULL, | ||
537 | .wb_init = &r600_wb_init, | ||
538 | .wb_fini = &r600_wb_fini, | ||
539 | .gart_enable = NULL, | ||
540 | .gart_disable = NULL, | ||
541 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, | ||
542 | .gart_set_page = &rs600_gart_set_page, | ||
543 | .cp_init = NULL, | ||
544 | .cp_fini = NULL, | ||
545 | .cp_disable = NULL, | ||
546 | .ring_start = NULL, | ||
547 | .ring_test = &r600_ring_test, | ||
548 | .ring_ib_execute = &r600_ring_ib_execute, | ||
549 | .ib_test = &r600_ib_test, | ||
550 | .irq_set = &r600_irq_set, | ||
551 | .irq_process = &r600_irq_process, | ||
552 | .fence_ring_emit = &r600_fence_ring_emit, | ||
553 | .cs_parse = &r600_cs_parse, | ||
554 | .copy_blit = &r600_copy_blit, | ||
555 | .copy_dma = &r600_copy_blit, | ||
556 | .copy = NULL, | ||
557 | .set_engine_clock = &radeon_atom_set_engine_clock, | ||
558 | .set_memory_clock = &radeon_atom_set_memory_clock, | ||
559 | .set_pcie_lanes = NULL, | ||
560 | .set_clock_gating = &radeon_atom_set_clock_gating, | ||
561 | .set_surface_reg = r600_set_surface_reg, | ||
562 | .clear_surface_reg = r600_clear_surface_reg, | ||
563 | .bandwidth_update = &r520_bandwidth_update, | ||
564 | }; | ||
565 | |||
566 | /* | ||
567 | * rv770,rv730,rv710,rv740 | ||
568 | */ | ||
569 | int rv770_init(struct radeon_device *rdev); | ||
570 | void rv770_fini(struct radeon_device *rdev); | ||
571 | int rv770_suspend(struct radeon_device *rdev); | ||
572 | int rv770_resume(struct radeon_device *rdev); | ||
573 | int rv770_gpu_reset(struct radeon_device *rdev); | ||
574 | |||
575 | static struct radeon_asic rv770_asic = { | ||
576 | .errata = NULL, | ||
577 | .init = &rv770_init, | ||
578 | .fini = &rv770_fini, | ||
579 | .suspend = &rv770_suspend, | ||
580 | .resume = &rv770_resume, | ||
581 | .cp_commit = &r600_cp_commit, | ||
582 | .vram_info = NULL, | ||
583 | .gpu_reset = &rv770_gpu_reset, | ||
584 | .mc_init = NULL, | ||
585 | .mc_fini = NULL, | ||
586 | .wb_init = &r600_wb_init, | ||
587 | .wb_fini = &r600_wb_fini, | ||
588 | .gart_enable = NULL, | ||
589 | .gart_disable = NULL, | ||
590 | .gart_tlb_flush = &r600_pcie_gart_tlb_flush, | ||
591 | .gart_set_page = &rs600_gart_set_page, | ||
592 | .cp_init = NULL, | ||
593 | .cp_fini = NULL, | ||
594 | .cp_disable = NULL, | ||
595 | .ring_start = NULL, | ||
596 | .ring_test = &r600_ring_test, | ||
597 | .ring_ib_execute = &r600_ring_ib_execute, | ||
598 | .ib_test = &r600_ib_test, | ||
599 | .irq_set = &r600_irq_set, | ||
600 | .irq_process = &r600_irq_process, | ||
601 | .fence_ring_emit = &r600_fence_ring_emit, | ||
602 | .cs_parse = &r600_cs_parse, | ||
603 | .copy_blit = &r600_copy_blit, | ||
604 | .copy_dma = &r600_copy_blit, | ||
605 | .copy = NULL, | ||
606 | .set_engine_clock = &radeon_atom_set_engine_clock, | ||
607 | .set_memory_clock = &radeon_atom_set_memory_clock, | ||
608 | .set_pcie_lanes = NULL, | ||
609 | .set_clock_gating = &radeon_atom_set_clock_gating, | ||
610 | .set_surface_reg = r600_set_surface_reg, | ||
611 | .clear_surface_reg = r600_clear_surface_reg, | ||
612 | .bandwidth_update = &r520_bandwidth_update, | ||
613 | }; | ||
460 | 614 | ||
461 | #endif | 615 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index bba9b4bd8f5c..a8fb392c9cd6 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -370,10 +370,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
370 | && record-> | 370 | && record-> |
371 | ucRecordType <= | 371 | ucRecordType <= |
372 | ATOM_MAX_OBJECT_RECORD_NUMBER) { | 372 | ATOM_MAX_OBJECT_RECORD_NUMBER) { |
373 | DRM_ERROR | ||
374 | ("record type %d\n", | ||
375 | record-> | ||
376 | ucRecordType); | ||
377 | switch (record-> | 373 | switch (record-> |
378 | ucRecordType) { | 374 | ucRecordType) { |
379 | case ATOM_I2C_RECORD_TYPE: | 375 | case ATOM_I2C_RECORD_TYPE: |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index a37cbce53181..152eef13197a 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -102,10 +102,12 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
102 | p1pll->reference_div = 12; | 102 | p1pll->reference_div = 12; |
103 | if (p2pll->reference_div < 2) | 103 | if (p2pll->reference_div < 2) |
104 | p2pll->reference_div = 12; | 104 | p2pll->reference_div = 12; |
105 | if (spll->reference_div < 2) | 105 | if (rdev->family < CHIP_RS600) { |
106 | spll->reference_div = | 106 | if (spll->reference_div < 2) |
107 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & | 107 | spll->reference_div = |
108 | RADEON_M_SPLL_REF_DIV_MASK; | 108 | RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & |
109 | RADEON_M_SPLL_REF_DIV_MASK; | ||
110 | } | ||
109 | if (mpll->reference_div < 2) | 111 | if (mpll->reference_div < 2) |
110 | mpll->reference_div = spll->reference_div; | 112 | mpll->reference_div = spll->reference_div; |
111 | } else { | 113 | } else { |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 7693f7c67bd3..f2469c511789 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -37,7 +37,7 @@ | |||
37 | /* | 37 | /* |
38 | * Clear GPU surface registers. | 38 | * Clear GPU surface registers. |
39 | */ | 39 | */ |
40 | static void radeon_surface_init(struct radeon_device *rdev) | 40 | void radeon_surface_init(struct radeon_device *rdev) |
41 | { | 41 | { |
42 | /* FIXME: check this out */ | 42 | /* FIXME: check this out */ |
43 | if (rdev->family < CHIP_R600) { | 43 | if (rdev->family < CHIP_R600) { |
@@ -56,7 +56,7 @@ static void radeon_surface_init(struct radeon_device *rdev) | |||
56 | /* | 56 | /* |
57 | * GPU scratch registers helpers function. | 57 | * GPU scratch registers helpers function. |
58 | */ | 58 | */ |
59 | static void radeon_scratch_init(struct radeon_device *rdev) | 59 | void radeon_scratch_init(struct radeon_device *rdev) |
60 | { | 60 | { |
61 | int i; | 61 | int i; |
62 | 62 | ||
@@ -156,16 +156,14 @@ int radeon_mc_setup(struct radeon_device *rdev) | |||
156 | tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1); | 156 | tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1); |
157 | rdev->mc.gtt_location = tmp; | 157 | rdev->mc.gtt_location = tmp; |
158 | } | 158 | } |
159 | DRM_INFO("radeon: VRAM %uM\n", rdev->mc.real_vram_size >> 20); | 159 | DRM_INFO("radeon: VRAM %uM\n", (unsigned)(rdev->mc.mc_vram_size >> 20)); |
160 | DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n", | 160 | DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n", |
161 | rdev->mc.vram_location, | 161 | (unsigned)rdev->mc.vram_location, |
162 | rdev->mc.vram_location + rdev->mc.mc_vram_size - 1); | 162 | (unsigned)(rdev->mc.vram_location + rdev->mc.mc_vram_size - 1)); |
163 | if (rdev->mc.real_vram_size != rdev->mc.mc_vram_size) | 163 | DRM_INFO("radeon: GTT %uM\n", (unsigned)(rdev->mc.gtt_size >> 20)); |
164 | DRM_INFO("radeon: VRAM less than aperture workaround enabled\n"); | ||
165 | DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20); | ||
166 | DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n", | 164 | DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n", |
167 | rdev->mc.gtt_location, | 165 | (unsigned)rdev->mc.gtt_location, |
168 | rdev->mc.gtt_location + rdev->mc.gtt_size - 1); | 166 | (unsigned)(rdev->mc.gtt_location + rdev->mc.gtt_size - 1)); |
169 | return 0; | 167 | return 0; |
170 | } | 168 | } |
171 | 169 | ||
@@ -205,6 +203,31 @@ static bool radeon_card_posted(struct radeon_device *rdev) | |||
205 | 203 | ||
206 | } | 204 | } |
207 | 205 | ||
206 | int radeon_dummy_page_init(struct radeon_device *rdev) | ||
207 | { | ||
208 | rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); | ||
209 | if (rdev->dummy_page.page == NULL) | ||
210 | return -ENOMEM; | ||
211 | rdev->dummy_page.addr = pci_map_page(rdev->pdev, rdev->dummy_page.page, | ||
212 | 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
213 | if (!rdev->dummy_page.addr) { | ||
214 | __free_page(rdev->dummy_page.page); | ||
215 | rdev->dummy_page.page = NULL; | ||
216 | return -ENOMEM; | ||
217 | } | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | void radeon_dummy_page_fini(struct radeon_device *rdev) | ||
222 | { | ||
223 | if (rdev->dummy_page.page == NULL) | ||
224 | return; | ||
225 | pci_unmap_page(rdev->pdev, rdev->dummy_page.addr, | ||
226 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
227 | __free_page(rdev->dummy_page.page); | ||
228 | rdev->dummy_page.page = NULL; | ||
229 | } | ||
230 | |||
208 | 231 | ||
209 | /* | 232 | /* |
210 | * Registers accessors functions. | 233 | * Registers accessors functions. |
@@ -323,9 +346,15 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
323 | case CHIP_RV635: | 346 | case CHIP_RV635: |
324 | case CHIP_RV670: | 347 | case CHIP_RV670: |
325 | case CHIP_RS780: | 348 | case CHIP_RS780: |
349 | case CHIP_RS880: | ||
350 | rdev->asic = &r600_asic; | ||
351 | break; | ||
326 | case CHIP_RV770: | 352 | case CHIP_RV770: |
327 | case CHIP_RV730: | 353 | case CHIP_RV730: |
328 | case CHIP_RV710: | 354 | case CHIP_RV710: |
355 | case CHIP_RV740: | ||
356 | rdev->asic = &rv770_asic; | ||
357 | break; | ||
329 | default: | 358 | default: |
330 | /* FIXME: not supported yet */ | 359 | /* FIXME: not supported yet */ |
331 | return -EINVAL; | 360 | return -EINVAL; |
@@ -448,7 +477,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
448 | struct pci_dev *pdev, | 477 | struct pci_dev *pdev, |
449 | uint32_t flags) | 478 | uint32_t flags) |
450 | { | 479 | { |
451 | int r, ret; | 480 | int r, ret = 0; |
452 | int dma_bits; | 481 | int dma_bits; |
453 | 482 | ||
454 | DRM_INFO("radeon: Initializing kernel modesetting.\n"); | 483 | DRM_INFO("radeon: Initializing kernel modesetting.\n"); |
@@ -487,10 +516,6 @@ int radeon_device_init(struct radeon_device *rdev, | |||
487 | if (r) { | 516 | if (r) { |
488 | return r; | 517 | return r; |
489 | } | 518 | } |
490 | r = radeon_init(rdev); | ||
491 | if (r) { | ||
492 | return r; | ||
493 | } | ||
494 | 519 | ||
495 | /* set DMA mask + need_dma32 flags. | 520 | /* set DMA mask + need_dma32 flags. |
496 | * PCIE - can handle 40-bits. | 521 | * PCIE - can handle 40-bits. |
@@ -521,111 +546,118 @@ int radeon_device_init(struct radeon_device *rdev, | |||
521 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); | 546 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); |
522 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); | 547 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); |
523 | 548 | ||
524 | /* Setup errata flags */ | 549 | rdev->new_init_path = false; |
525 | radeon_errata(rdev); | 550 | r = radeon_init(rdev); |
526 | /* Initialize scratch registers */ | 551 | if (r) { |
527 | radeon_scratch_init(rdev); | 552 | return r; |
528 | /* Initialize surface registers */ | 553 | } |
529 | radeon_surface_init(rdev); | 554 | if (!rdev->new_init_path) { |
530 | 555 | /* Setup errata flags */ | |
531 | /* TODO: disable VGA need to use VGA request */ | 556 | radeon_errata(rdev); |
532 | /* BIOS*/ | 557 | /* Initialize scratch registers */ |
533 | if (!radeon_get_bios(rdev)) { | 558 | radeon_scratch_init(rdev); |
534 | if (ASIC_IS_AVIVO(rdev)) | 559 | /* Initialize surface registers */ |
535 | return -EINVAL; | 560 | radeon_surface_init(rdev); |
536 | } | 561 | |
537 | if (rdev->is_atom_bios) { | 562 | /* TODO: disable VGA need to use VGA request */ |
538 | r = radeon_atombios_init(rdev); | 563 | /* BIOS*/ |
564 | if (!radeon_get_bios(rdev)) { | ||
565 | if (ASIC_IS_AVIVO(rdev)) | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | if (rdev->is_atom_bios) { | ||
569 | r = radeon_atombios_init(rdev); | ||
570 | if (r) { | ||
571 | return r; | ||
572 | } | ||
573 | } else { | ||
574 | r = radeon_combios_init(rdev); | ||
575 | if (r) { | ||
576 | return r; | ||
577 | } | ||
578 | } | ||
579 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
580 | if (radeon_gpu_reset(rdev)) { | ||
581 | /* FIXME: what do we want to do here ? */ | ||
582 | } | ||
583 | /* check if cards are posted or not */ | ||
584 | if (!radeon_card_posted(rdev) && rdev->bios) { | ||
585 | DRM_INFO("GPU not posted. posting now...\n"); | ||
586 | if (rdev->is_atom_bios) { | ||
587 | atom_asic_init(rdev->mode_info.atom_context); | ||
588 | } else { | ||
589 | radeon_combios_asic_init(rdev->ddev); | ||
590 | } | ||
591 | } | ||
592 | /* Initialize clocks */ | ||
593 | r = radeon_clocks_init(rdev); | ||
539 | if (r) { | 594 | if (r) { |
540 | return r; | 595 | return r; |
541 | } | 596 | } |
542 | } else { | 597 | /* Get vram informations */ |
543 | r = radeon_combios_init(rdev); | 598 | radeon_vram_info(rdev); |
599 | |||
600 | /* Add an MTRR for the VRAM */ | ||
601 | rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size, | ||
602 | MTRR_TYPE_WRCOMB, 1); | ||
603 | DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n", | ||
604 | (unsigned)(rdev->mc.mc_vram_size >> 20), | ||
605 | (unsigned)(rdev->mc.aper_size >> 20)); | ||
606 | DRM_INFO("RAM width %dbits %cDR\n", | ||
607 | rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S'); | ||
608 | /* Initialize memory controller (also test AGP) */ | ||
609 | r = radeon_mc_init(rdev); | ||
544 | if (r) { | 610 | if (r) { |
545 | return r; | 611 | return r; |
546 | } | 612 | } |
547 | } | 613 | /* Fence driver */ |
548 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | 614 | r = radeon_fence_driver_init(rdev); |
549 | if (radeon_gpu_reset(rdev)) { | ||
550 | /* FIXME: what do we want to do here ? */ | ||
551 | } | ||
552 | /* check if cards are posted or not */ | ||
553 | if (!radeon_card_posted(rdev) && rdev->bios) { | ||
554 | DRM_INFO("GPU not posted. posting now...\n"); | ||
555 | if (rdev->is_atom_bios) { | ||
556 | atom_asic_init(rdev->mode_info.atom_context); | ||
557 | } else { | ||
558 | radeon_combios_asic_init(rdev->ddev); | ||
559 | } | ||
560 | } | ||
561 | /* Initialize clocks */ | ||
562 | r = radeon_clocks_init(rdev); | ||
563 | if (r) { | ||
564 | return r; | ||
565 | } | ||
566 | /* Get vram informations */ | ||
567 | radeon_vram_info(rdev); | ||
568 | |||
569 | /* Add an MTRR for the VRAM */ | ||
570 | rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size, | ||
571 | MTRR_TYPE_WRCOMB, 1); | ||
572 | DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n", | ||
573 | rdev->mc.real_vram_size >> 20, | ||
574 | (unsigned)rdev->mc.aper_size >> 20); | ||
575 | DRM_INFO("RAM width %dbits %cDR\n", | ||
576 | rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S'); | ||
577 | /* Initialize memory controller (also test AGP) */ | ||
578 | r = radeon_mc_init(rdev); | ||
579 | if (r) { | ||
580 | return r; | ||
581 | } | ||
582 | /* Fence driver */ | ||
583 | r = radeon_fence_driver_init(rdev); | ||
584 | if (r) { | ||
585 | return r; | ||
586 | } | ||
587 | r = radeon_irq_kms_init(rdev); | ||
588 | if (r) { | ||
589 | return r; | ||
590 | } | ||
591 | /* Memory manager */ | ||
592 | r = radeon_object_init(rdev); | ||
593 | if (r) { | ||
594 | return r; | ||
595 | } | ||
596 | /* Initialize GART (initialize after TTM so we can allocate | ||
597 | * memory through TTM but finalize after TTM) */ | ||
598 | r = radeon_gart_enable(rdev); | ||
599 | if (!r) { | ||
600 | r = radeon_gem_init(rdev); | ||
601 | } | ||
602 | |||
603 | /* 1M ring buffer */ | ||
604 | if (!r) { | ||
605 | r = radeon_cp_init(rdev, 1024 * 1024); | ||
606 | } | ||
607 | if (!r) { | ||
608 | r = radeon_wb_init(rdev); | ||
609 | if (r) { | 615 | if (r) { |
610 | DRM_ERROR("radeon: failled initializing WB (%d).\n", r); | ||
611 | return r; | 616 | return r; |
612 | } | 617 | } |
613 | } | 618 | r = radeon_irq_kms_init(rdev); |
614 | if (!r) { | ||
615 | r = radeon_ib_pool_init(rdev); | ||
616 | if (r) { | 619 | if (r) { |
617 | DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); | ||
618 | return r; | 620 | return r; |
619 | } | 621 | } |
620 | } | 622 | /* Memory manager */ |
621 | if (!r) { | 623 | r = radeon_object_init(rdev); |
622 | r = radeon_ib_test(rdev); | ||
623 | if (r) { | 624 | if (r) { |
624 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | ||
625 | return r; | 625 | return r; |
626 | } | 626 | } |
627 | /* Initialize GART (initialize after TTM so we can allocate | ||
628 | * memory through TTM but finalize after TTM) */ | ||
629 | r = radeon_gart_enable(rdev); | ||
630 | if (!r) { | ||
631 | r = radeon_gem_init(rdev); | ||
632 | } | ||
633 | |||
634 | /* 1M ring buffer */ | ||
635 | if (!r) { | ||
636 | r = radeon_cp_init(rdev, 1024 * 1024); | ||
637 | } | ||
638 | if (!r) { | ||
639 | r = radeon_wb_init(rdev); | ||
640 | if (r) { | ||
641 | DRM_ERROR("radeon: failled initializing WB (%d).\n", r); | ||
642 | return r; | ||
643 | } | ||
644 | } | ||
645 | if (!r) { | ||
646 | r = radeon_ib_pool_init(rdev); | ||
647 | if (r) { | ||
648 | DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); | ||
649 | return r; | ||
650 | } | ||
651 | } | ||
652 | if (!r) { | ||
653 | r = radeon_ib_test(rdev); | ||
654 | if (r) { | ||
655 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | ||
656 | return r; | ||
657 | } | ||
658 | } | ||
659 | ret = r; | ||
627 | } | 660 | } |
628 | ret = r; | ||
629 | r = radeon_modeset_init(rdev); | 661 | r = radeon_modeset_init(rdev); |
630 | if (r) { | 662 | if (r) { |
631 | return r; | 663 | return r; |
@@ -651,26 +683,29 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
651 | rdev->shutdown = true; | 683 | rdev->shutdown = true; |
652 | /* Order matter so becarefull if you rearrange anythings */ | 684 | /* Order matter so becarefull if you rearrange anythings */ |
653 | radeon_modeset_fini(rdev); | 685 | radeon_modeset_fini(rdev); |
654 | radeon_ib_pool_fini(rdev); | 686 | if (!rdev->new_init_path) { |
655 | radeon_cp_fini(rdev); | 687 | radeon_ib_pool_fini(rdev); |
656 | radeon_wb_fini(rdev); | 688 | radeon_cp_fini(rdev); |
657 | radeon_gem_fini(rdev); | 689 | radeon_wb_fini(rdev); |
658 | radeon_object_fini(rdev); | 690 | radeon_gem_fini(rdev); |
659 | /* mc_fini must be after object_fini */ | 691 | radeon_mc_fini(rdev); |
660 | radeon_mc_fini(rdev); | ||
661 | #if __OS_HAS_AGP | 692 | #if __OS_HAS_AGP |
662 | radeon_agp_fini(rdev); | 693 | radeon_agp_fini(rdev); |
663 | #endif | 694 | #endif |
664 | radeon_irq_kms_fini(rdev); | 695 | radeon_irq_kms_fini(rdev); |
665 | radeon_fence_driver_fini(rdev); | 696 | radeon_fence_driver_fini(rdev); |
666 | radeon_clocks_fini(rdev); | 697 | radeon_clocks_fini(rdev); |
667 | if (rdev->is_atom_bios) { | 698 | radeon_object_fini(rdev); |
668 | radeon_atombios_fini(rdev); | 699 | if (rdev->is_atom_bios) { |
700 | radeon_atombios_fini(rdev); | ||
701 | } else { | ||
702 | radeon_combios_fini(rdev); | ||
703 | } | ||
704 | kfree(rdev->bios); | ||
705 | rdev->bios = NULL; | ||
669 | } else { | 706 | } else { |
670 | radeon_combios_fini(rdev); | 707 | radeon_fini(rdev); |
671 | } | 708 | } |
672 | kfree(rdev->bios); | ||
673 | rdev->bios = NULL; | ||
674 | iounmap(rdev->rmmio); | 709 | iounmap(rdev->rmmio); |
675 | rdev->rmmio = NULL; | 710 | rdev->rmmio = NULL; |
676 | } | 711 | } |
@@ -708,9 +743,12 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
708 | /* wait for gpu to finish processing current batch */ | 743 | /* wait for gpu to finish processing current batch */ |
709 | radeon_fence_wait_last(rdev); | 744 | radeon_fence_wait_last(rdev); |
710 | 745 | ||
711 | radeon_cp_disable(rdev); | 746 | if (!rdev->new_init_path) { |
712 | radeon_gart_disable(rdev); | 747 | radeon_cp_disable(rdev); |
713 | 748 | radeon_gart_disable(rdev); | |
749 | } else { | ||
750 | radeon_suspend(rdev); | ||
751 | } | ||
714 | /* evict remaining vram memory */ | 752 | /* evict remaining vram memory */ |
715 | radeon_object_evict_vram(rdev); | 753 | radeon_object_evict_vram(rdev); |
716 | 754 | ||
@@ -746,33 +784,37 @@ int radeon_resume_kms(struct drm_device *dev) | |||
746 | if (radeon_gpu_reset(rdev)) { | 784 | if (radeon_gpu_reset(rdev)) { |
747 | /* FIXME: what do we want to do here ? */ | 785 | /* FIXME: what do we want to do here ? */ |
748 | } | 786 | } |
749 | /* post card */ | 787 | if (!rdev->new_init_path) { |
750 | if (rdev->is_atom_bios) { | 788 | /* post card */ |
751 | atom_asic_init(rdev->mode_info.atom_context); | 789 | if (rdev->is_atom_bios) { |
790 | atom_asic_init(rdev->mode_info.atom_context); | ||
791 | } else { | ||
792 | radeon_combios_asic_init(rdev->ddev); | ||
793 | } | ||
794 | /* Initialize clocks */ | ||
795 | r = radeon_clocks_init(rdev); | ||
796 | if (r) { | ||
797 | release_console_sem(); | ||
798 | return r; | ||
799 | } | ||
800 | /* Enable IRQ */ | ||
801 | rdev->irq.sw_int = true; | ||
802 | radeon_irq_set(rdev); | ||
803 | /* Initialize GPU Memory Controller */ | ||
804 | r = radeon_mc_init(rdev); | ||
805 | if (r) { | ||
806 | goto out; | ||
807 | } | ||
808 | r = radeon_gart_enable(rdev); | ||
809 | if (r) { | ||
810 | goto out; | ||
811 | } | ||
812 | r = radeon_cp_init(rdev, rdev->cp.ring_size); | ||
813 | if (r) { | ||
814 | goto out; | ||
815 | } | ||
752 | } else { | 816 | } else { |
753 | radeon_combios_asic_init(rdev->ddev); | 817 | radeon_resume(rdev); |
754 | } | ||
755 | /* Initialize clocks */ | ||
756 | r = radeon_clocks_init(rdev); | ||
757 | if (r) { | ||
758 | release_console_sem(); | ||
759 | return r; | ||
760 | } | ||
761 | /* Enable IRQ */ | ||
762 | rdev->irq.sw_int = true; | ||
763 | radeon_irq_set(rdev); | ||
764 | /* Initialize GPU Memory Controller */ | ||
765 | r = radeon_mc_init(rdev); | ||
766 | if (r) { | ||
767 | goto out; | ||
768 | } | ||
769 | r = radeon_gart_enable(rdev); | ||
770 | if (r) { | ||
771 | goto out; | ||
772 | } | ||
773 | r = radeon_cp_init(rdev, rdev->cp.ring_size); | ||
774 | if (r) { | ||
775 | goto out; | ||
776 | } | 818 | } |
777 | out: | 819 | out: |
778 | fb_set_suspend(rdev->fbdev_info, 0); | 820 | fb_set_suspend(rdev->fbdev_info, 0); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 40294a07976f..c7b185924f6c 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -356,6 +356,12 @@ typedef struct drm_radeon_private { | |||
356 | int r700_sc_hiz_tile_fifo_size; | 356 | int r700_sc_hiz_tile_fifo_size; |
357 | int r700_sc_earlyz_tile_fifo_fize; | 357 | int r700_sc_earlyz_tile_fifo_fize; |
358 | 358 | ||
359 | struct mutex cs_mutex; | ||
360 | u32 cs_id_scnt; | ||
361 | u32 cs_id_wcnt; | ||
362 | /* r6xx/r7xx drm blit vertex buffer */ | ||
363 | struct drm_buf *blit_vb; | ||
364 | |||
359 | /* firmware */ | 365 | /* firmware */ |
360 | const struct firmware *me_fw, *pfp_fw; | 366 | const struct firmware *me_fw, *pfp_fw; |
361 | } drm_radeon_private_t; | 367 | } drm_radeon_private_t; |
@@ -396,6 +402,9 @@ static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, | |||
396 | (off >= gart_start && off <= gart_end)); | 402 | (off >= gart_start && off <= gart_end)); |
397 | } | 403 | } |
398 | 404 | ||
405 | /* radeon_state.c */ | ||
406 | extern void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf); | ||
407 | |||
399 | /* radeon_cp.c */ | 408 | /* radeon_cp.c */ |
400 | extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); | 409 | extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); |
401 | extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv); | 410 | extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv); |
@@ -487,6 +496,22 @@ extern int r600_cp_dispatch_indirect(struct drm_device *dev, | |||
487 | struct drm_buf *buf, int start, int end); | 496 | struct drm_buf *buf, int start, int end); |
488 | extern int r600_page_table_init(struct drm_device *dev); | 497 | extern int r600_page_table_init(struct drm_device *dev); |
489 | extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); | 498 | extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); |
499 | extern int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); | ||
500 | extern void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv); | ||
501 | extern int r600_cp_dispatch_texture(struct drm_device *dev, | ||
502 | struct drm_file *file_priv, | ||
503 | drm_radeon_texture_t *tex, | ||
504 | drm_radeon_tex_image_t *image); | ||
505 | /* r600_blit.c */ | ||
506 | extern int r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv); | ||
507 | extern void r600_done_blit_copy(struct drm_device *dev); | ||
508 | extern void r600_blit_copy(struct drm_device *dev, | ||
509 | uint64_t src_gpu_addr, uint64_t dst_gpu_addr, | ||
510 | int size_bytes); | ||
511 | extern void r600_blit_swap(struct drm_device *dev, | ||
512 | uint64_t src_gpu_addr, uint64_t dst_gpu_addr, | ||
513 | int sx, int sy, int dx, int dy, | ||
514 | int w, int h, int src_pitch, int dst_pitch, int cpp); | ||
490 | 515 | ||
491 | /* Flags for stats.boxes | 516 | /* Flags for stats.boxes |
492 | */ | 517 | */ |
@@ -1114,13 +1139,71 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); | |||
1114 | # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 | 1139 | # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 |
1115 | # define RADEON_CNTL_SET_SCISSORS 0xC0001E00 | 1140 | # define RADEON_CNTL_SET_SCISSORS 0xC0001E00 |
1116 | 1141 | ||
1117 | # define R600_IT_INDIRECT_BUFFER 0x00003200 | 1142 | # define R600_IT_INDIRECT_BUFFER_END 0x00001700 |
1118 | # define R600_IT_ME_INITIALIZE 0x00004400 | 1143 | # define R600_IT_SET_PREDICATION 0x00002000 |
1144 | # define R600_IT_REG_RMW 0x00002100 | ||
1145 | # define R600_IT_COND_EXEC 0x00002200 | ||
1146 | # define R600_IT_PRED_EXEC 0x00002300 | ||
1147 | # define R600_IT_START_3D_CMDBUF 0x00002400 | ||
1148 | # define R600_IT_DRAW_INDEX_2 0x00002700 | ||
1149 | # define R600_IT_CONTEXT_CONTROL 0x00002800 | ||
1150 | # define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900 | ||
1151 | # define R600_IT_INDEX_TYPE 0x00002A00 | ||
1152 | # define R600_IT_DRAW_INDEX 0x00002B00 | ||
1153 | # define R600_IT_DRAW_INDEX_AUTO 0x00002D00 | ||
1154 | # define R600_IT_DRAW_INDEX_IMMD 0x00002E00 | ||
1155 | # define R600_IT_NUM_INSTANCES 0x00002F00 | ||
1156 | # define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400 | ||
1157 | # define R600_IT_INDIRECT_BUFFER_MP 0x00003800 | ||
1158 | # define R600_IT_MEM_SEMAPHORE 0x00003900 | ||
1159 | # define R600_IT_MPEG_INDEX 0x00003A00 | ||
1160 | # define R600_IT_WAIT_REG_MEM 0x00003C00 | ||
1161 | # define R600_IT_MEM_WRITE 0x00003D00 | ||
1162 | # define R600_IT_INDIRECT_BUFFER 0x00003200 | ||
1163 | # define R600_IT_CP_INTERRUPT 0x00004000 | ||
1164 | # define R600_IT_SURFACE_SYNC 0x00004300 | ||
1165 | # define R600_CB0_DEST_BASE_ENA (1 << 6) | ||
1166 | # define R600_TC_ACTION_ENA (1 << 23) | ||
1167 | # define R600_VC_ACTION_ENA (1 << 24) | ||
1168 | # define R600_CB_ACTION_ENA (1 << 25) | ||
1169 | # define R600_DB_ACTION_ENA (1 << 26) | ||
1170 | # define R600_SH_ACTION_ENA (1 << 27) | ||
1171 | # define R600_SMX_ACTION_ENA (1 << 28) | ||
1172 | # define R600_IT_ME_INITIALIZE 0x00004400 | ||
1119 | # define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) | 1173 | # define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) |
1120 | # define R600_IT_EVENT_WRITE 0x00004600 | 1174 | # define R600_IT_COND_WRITE 0x00004500 |
1121 | # define R600_IT_SET_CONFIG_REG 0x00006800 | 1175 | # define R600_IT_EVENT_WRITE 0x00004600 |
1122 | # define R600_SET_CONFIG_REG_OFFSET 0x00008000 | 1176 | # define R600_IT_EVENT_WRITE_EOP 0x00004700 |
1123 | # define R600_SET_CONFIG_REG_END 0x0000ac00 | 1177 | # define R600_IT_ONE_REG_WRITE 0x00005700 |
1178 | # define R600_IT_SET_CONFIG_REG 0x00006800 | ||
1179 | # define R600_SET_CONFIG_REG_OFFSET 0x00008000 | ||
1180 | # define R600_SET_CONFIG_REG_END 0x0000ac00 | ||
1181 | # define R600_IT_SET_CONTEXT_REG 0x00006900 | ||
1182 | # define R600_SET_CONTEXT_REG_OFFSET 0x00028000 | ||
1183 | # define R600_SET_CONTEXT_REG_END 0x00029000 | ||
1184 | # define R600_IT_SET_ALU_CONST 0x00006A00 | ||
1185 | # define R600_SET_ALU_CONST_OFFSET 0x00030000 | ||
1186 | # define R600_SET_ALU_CONST_END 0x00032000 | ||
1187 | # define R600_IT_SET_BOOL_CONST 0x00006B00 | ||
1188 | # define R600_SET_BOOL_CONST_OFFSET 0x0003e380 | ||
1189 | # define R600_SET_BOOL_CONST_END 0x00040000 | ||
1190 | # define R600_IT_SET_LOOP_CONST 0x00006C00 | ||
1191 | # define R600_SET_LOOP_CONST_OFFSET 0x0003e200 | ||
1192 | # define R600_SET_LOOP_CONST_END 0x0003e380 | ||
1193 | # define R600_IT_SET_RESOURCE 0x00006D00 | ||
1194 | # define R600_SET_RESOURCE_OFFSET 0x00038000 | ||
1195 | # define R600_SET_RESOURCE_END 0x0003c000 | ||
1196 | # define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0 | ||
1197 | # define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1 | ||
1198 | # define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2 | ||
1199 | # define R600_SQ_TEX_VTX_VALID_BUFFER 0x3 | ||
1200 | # define R600_IT_SET_SAMPLER 0x00006E00 | ||
1201 | # define R600_SET_SAMPLER_OFFSET 0x0003c000 | ||
1202 | # define R600_SET_SAMPLER_END 0x0003cff0 | ||
1203 | # define R600_IT_SET_CTL_CONST 0x00006F00 | ||
1204 | # define R600_SET_CTL_CONST_OFFSET 0x0003cff0 | ||
1205 | # define R600_SET_CTL_CONST_END 0x0003e200 | ||
1206 | # define R600_IT_SURFACE_BASE_UPDATE 0x00007300 | ||
1124 | 1207 | ||
1125 | #define RADEON_CP_PACKET_MASK 0xC0000000 | 1208 | #define RADEON_CP_PACKET_MASK 0xC0000000 |
1126 | #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 | 1209 | #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 |
@@ -1598,6 +1681,52 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); | |||
1598 | #define R600_CB_COLOR7_BASE 0x2805c | 1681 | #define R600_CB_COLOR7_BASE 0x2805c |
1599 | #define R600_CB_COLOR7_FRAG 0x280fc | 1682 | #define R600_CB_COLOR7_FRAG 0x280fc |
1600 | 1683 | ||
1684 | #define R600_CB_COLOR0_SIZE 0x28060 | ||
1685 | #define R600_CB_COLOR0_VIEW 0x28080 | ||
1686 | #define R600_CB_COLOR0_INFO 0x280a0 | ||
1687 | #define R600_CB_COLOR0_TILE 0x280c0 | ||
1688 | #define R600_CB_COLOR0_FRAG 0x280e0 | ||
1689 | #define R600_CB_COLOR0_MASK 0x28100 | ||
1690 | |||
1691 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 | ||
1692 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 | ||
1693 | #define R600_CP_COHER_BASE 0x85f8 | ||
1694 | #define R600_DB_DEPTH_BASE 0x2800c | ||
1695 | #define R600_SQ_PGM_START_FS 0x28894 | ||
1696 | #define R600_SQ_PGM_START_ES 0x28880 | ||
1697 | #define R600_SQ_PGM_START_VS 0x28858 | ||
1698 | #define R600_SQ_PGM_RESOURCES_VS 0x28868 | ||
1699 | #define R600_SQ_PGM_CF_OFFSET_VS 0x288d0 | ||
1700 | #define R600_SQ_PGM_START_GS 0x2886c | ||
1701 | #define R600_SQ_PGM_START_PS 0x28840 | ||
1702 | #define R600_SQ_PGM_RESOURCES_PS 0x28850 | ||
1703 | #define R600_SQ_PGM_EXPORTS_PS 0x28854 | ||
1704 | #define R600_SQ_PGM_CF_OFFSET_PS 0x288cc | ||
1705 | #define R600_VGT_DMA_BASE 0x287e8 | ||
1706 | #define R600_VGT_DMA_BASE_HI 0x287e4 | ||
1707 | #define R600_VGT_STRMOUT_BASE_OFFSET_0 0x28b10 | ||
1708 | #define R600_VGT_STRMOUT_BASE_OFFSET_1 0x28b14 | ||
1709 | #define R600_VGT_STRMOUT_BASE_OFFSET_2 0x28b18 | ||
1710 | #define R600_VGT_STRMOUT_BASE_OFFSET_3 0x28b1c | ||
1711 | #define R600_VGT_STRMOUT_BASE_OFFSET_HI_0 0x28b44 | ||
1712 | #define R600_VGT_STRMOUT_BASE_OFFSET_HI_1 0x28b48 | ||
1713 | #define R600_VGT_STRMOUT_BASE_OFFSET_HI_2 0x28b4c | ||
1714 | #define R600_VGT_STRMOUT_BASE_OFFSET_HI_3 0x28b50 | ||
1715 | #define R600_VGT_STRMOUT_BUFFER_BASE_0 0x28ad8 | ||
1716 | #define R600_VGT_STRMOUT_BUFFER_BASE_1 0x28ae8 | ||
1717 | #define R600_VGT_STRMOUT_BUFFER_BASE_2 0x28af8 | ||
1718 | #define R600_VGT_STRMOUT_BUFFER_BASE_3 0x28b08 | ||
1719 | #define R600_VGT_STRMOUT_BUFFER_OFFSET_0 0x28adc | ||
1720 | #define R600_VGT_STRMOUT_BUFFER_OFFSET_1 0x28aec | ||
1721 | #define R600_VGT_STRMOUT_BUFFER_OFFSET_2 0x28afc | ||
1722 | #define R600_VGT_STRMOUT_BUFFER_OFFSET_3 0x28b0c | ||
1723 | |||
1724 | #define R600_VGT_PRIMITIVE_TYPE 0x8958 | ||
1725 | |||
1726 | #define R600_PA_SC_SCREEN_SCISSOR_TL 0x28030 | ||
1727 | #define R600_PA_SC_GENERIC_SCISSOR_TL 0x28240 | ||
1728 | #define R600_PA_SC_WINDOW_SCISSOR_TL 0x28204 | ||
1729 | |||
1601 | #define R600_TC_CNTL 0x9608 | 1730 | #define R600_TC_CNTL 0x9608 |
1602 | # define R600_TC_L2_SIZE(x) ((x) << 5) | 1731 | # define R600_TC_L2_SIZE(x) ((x) << 5) |
1603 | # define R600_L2_DISABLE_LATE_HIT (1 << 9) | 1732 | # define R600_L2_DISABLE_LATE_HIT (1 << 9) |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index b4e48dd2e859..506dd4dd3a24 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -53,9 +53,9 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) | |||
53 | * away | 53 | * away |
54 | */ | 54 | */ |
55 | WREG32(rdev->fence_drv.scratch_reg, fence->seq); | 55 | WREG32(rdev->fence_drv.scratch_reg, fence->seq); |
56 | } else { | 56 | } else |
57 | radeon_fence_ring_emit(rdev, fence); | 57 | radeon_fence_ring_emit(rdev, fence); |
58 | } | 58 | |
59 | fence->emited = true; | 59 | fence->emited = true; |
60 | fence->timeout = jiffies + ((2000 * HZ) / 1000); | 60 | fence->timeout = jiffies + ((2000 * HZ) / 1000); |
61 | list_del(&fence->list); | 61 | list_del(&fence->list); |
@@ -168,7 +168,47 @@ bool radeon_fence_signaled(struct radeon_fence *fence) | |||
168 | return signaled; | 168 | return signaled; |
169 | } | 169 | } |
170 | 170 | ||
171 | int radeon_fence_wait(struct radeon_fence *fence, bool interruptible) | 171 | int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy) |
172 | { | ||
173 | struct radeon_device *rdev; | ||
174 | unsigned long cur_jiffies; | ||
175 | unsigned long timeout; | ||
176 | int ret = 0; | ||
177 | |||
178 | cur_jiffies = jiffies; | ||
179 | timeout = HZ / 100; | ||
180 | |||
181 | if (time_after(fence->timeout, cur_jiffies)) { | ||
182 | timeout = fence->timeout - cur_jiffies; | ||
183 | } | ||
184 | |||
185 | rdev = fence->rdev; | ||
186 | |||
187 | __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); | ||
188 | |||
189 | while (1) { | ||
190 | if (radeon_fence_signaled(fence)) | ||
191 | break; | ||
192 | |||
193 | if (time_after_eq(jiffies, timeout)) { | ||
194 | ret = -EBUSY; | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | if (lazy) | ||
199 | schedule_timeout(1); | ||
200 | |||
201 | if (intr && signal_pending(current)) { | ||
202 | ret = -ERESTART; | ||
203 | break; | ||
204 | } | ||
205 | } | ||
206 | __set_current_state(TASK_RUNNING); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | |||
211 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) | ||
172 | { | 212 | { |
173 | struct radeon_device *rdev; | 213 | struct radeon_device *rdev; |
174 | unsigned long cur_jiffies; | 214 | unsigned long cur_jiffies; |
@@ -176,7 +216,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible) | |||
176 | bool expired = false; | 216 | bool expired = false; |
177 | int r; | 217 | int r; |
178 | 218 | ||
179 | |||
180 | if (fence == NULL) { | 219 | if (fence == NULL) { |
181 | WARN(1, "Querying an invalid fence : %p !\n", fence); | 220 | WARN(1, "Querying an invalid fence : %p !\n", fence); |
182 | return 0; | 221 | return 0; |
@@ -185,13 +224,18 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible) | |||
185 | if (radeon_fence_signaled(fence)) { | 224 | if (radeon_fence_signaled(fence)) { |
186 | return 0; | 225 | return 0; |
187 | } | 226 | } |
227 | |||
228 | if (rdev->family >= CHIP_R600) | ||
229 | return r600_fence_wait(fence, intr, 0); | ||
230 | |||
188 | retry: | 231 | retry: |
189 | cur_jiffies = jiffies; | 232 | cur_jiffies = jiffies; |
190 | timeout = HZ / 100; | 233 | timeout = HZ / 100; |
191 | if (time_after(fence->timeout, cur_jiffies)) { | 234 | if (time_after(fence->timeout, cur_jiffies)) { |
192 | timeout = fence->timeout - cur_jiffies; | 235 | timeout = fence->timeout - cur_jiffies; |
193 | } | 236 | } |
194 | if (interruptible) { | 237 | |
238 | if (intr) { | ||
195 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, | 239 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
196 | radeon_fence_signaled(fence), timeout); | 240 | radeon_fence_signaled(fence), timeout); |
197 | if (unlikely(r == -ERESTARTSYS)) { | 241 | if (unlikely(r == -ERESTARTSYS)) { |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 28be2f1165cb..21da871a793c 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -3255,6 +3255,24 @@ | |||
3255 | #define RADEON_CP_RB_WPTR 0x0714 | 3255 | #define RADEON_CP_RB_WPTR 0x0714 |
3256 | #define RADEON_CP_RB_RPTR_WR 0x071c | 3256 | #define RADEON_CP_RB_RPTR_WR 0x071c |
3257 | 3257 | ||
3258 | #define RADEON_SCRATCH_UMSK 0x0770 | ||
3259 | #define RADEON_SCRATCH_ADDR 0x0774 | ||
3260 | |||
3261 | #define R600_CP_RB_BASE 0xc100 | ||
3262 | #define R600_CP_RB_CNTL 0xc104 | ||
3263 | # define R600_RB_BUFSZ(x) ((x) << 0) | ||
3264 | # define R600_RB_BLKSZ(x) ((x) << 8) | ||
3265 | # define R600_RB_NO_UPDATE (1 << 27) | ||
3266 | # define R600_RB_RPTR_WR_ENA (1 << 31) | ||
3267 | #define R600_CP_RB_RPTR_WR 0xc108 | ||
3268 | #define R600_CP_RB_RPTR_ADDR 0xc10c | ||
3269 | #define R600_CP_RB_RPTR_ADDR_HI 0xc110 | ||
3270 | #define R600_CP_RB_WPTR 0xc114 | ||
3271 | #define R600_CP_RB_WPTR_ADDR 0xc118 | ||
3272 | #define R600_CP_RB_WPTR_ADDR_HI 0xc11c | ||
3273 | #define R600_CP_RB_RPTR 0x8700 | ||
3274 | #define R600_CP_RB_WPTR_DELAY 0x8704 | ||
3275 | |||
3258 | #define RADEON_CP_IB_BASE 0x0738 | 3276 | #define RADEON_CP_IB_BASE 0x0738 |
3259 | #define RADEON_CP_IB_BUFSZ 0x073c | 3277 | #define RADEON_CP_IB_BUFSZ 0x073c |
3260 | 3278 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 60d159308b88..aa9837a6aa75 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -110,7 +110,6 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | |||
110 | return; | 110 | return; |
111 | } | 111 | } |
112 | list_del(&tmp->list); | 112 | list_del(&tmp->list); |
113 | INIT_LIST_HEAD(&tmp->list); | ||
114 | if (tmp->fence) { | 113 | if (tmp->fence) { |
115 | radeon_fence_unref(&tmp->fence); | 114 | radeon_fence_unref(&tmp->fence); |
116 | } | 115 | } |
@@ -119,19 +118,11 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | |||
119 | mutex_unlock(&rdev->ib_pool.mutex); | 118 | mutex_unlock(&rdev->ib_pool.mutex); |
120 | } | 119 | } |
121 | 120 | ||
122 | static void radeon_ib_align(struct radeon_device *rdev, struct radeon_ib *ib) | ||
123 | { | ||
124 | while ((ib->length_dw & rdev->cp.align_mask)) { | ||
125 | ib->ptr[ib->length_dw++] = PACKET2(0); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | 121 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) |
130 | { | 122 | { |
131 | int r = 0; | 123 | int r = 0; |
132 | 124 | ||
133 | mutex_lock(&rdev->ib_pool.mutex); | 125 | mutex_lock(&rdev->ib_pool.mutex); |
134 | radeon_ib_align(rdev, ib); | ||
135 | if (!ib->length_dw || !rdev->cp.ready) { | 126 | if (!ib->length_dw || !rdev->cp.ready) { |
136 | /* TODO: Nothings in the ib we should report. */ | 127 | /* TODO: Nothings in the ib we should report. */ |
137 | mutex_unlock(&rdev->ib_pool.mutex); | 128 | mutex_unlock(&rdev->ib_pool.mutex); |
@@ -145,9 +136,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
145 | mutex_unlock(&rdev->ib_pool.mutex); | 136 | mutex_unlock(&rdev->ib_pool.mutex); |
146 | return r; | 137 | return r; |
147 | } | 138 | } |
148 | radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1)); | 139 | radeon_ring_ib_execute(rdev, ib); |
149 | radeon_ring_write(rdev, ib->gpu_addr); | ||
150 | radeon_ring_write(rdev, ib->length_dw); | ||
151 | radeon_fence_emit(rdev, ib->fence); | 140 | radeon_fence_emit(rdev, ib->fence); |
152 | radeon_ring_unlock_commit(rdev); | 141 | radeon_ring_unlock_commit(rdev); |
153 | list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs); | 142 | list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs); |
@@ -215,69 +204,16 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
215 | mutex_unlock(&rdev->ib_pool.mutex); | 204 | mutex_unlock(&rdev->ib_pool.mutex); |
216 | } | 205 | } |
217 | 206 | ||
218 | int radeon_ib_test(struct radeon_device *rdev) | ||
219 | { | ||
220 | struct radeon_ib *ib; | ||
221 | uint32_t scratch; | ||
222 | uint32_t tmp = 0; | ||
223 | unsigned i; | ||
224 | int r; | ||
225 | |||
226 | r = radeon_scratch_get(rdev, &scratch); | ||
227 | if (r) { | ||
228 | DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); | ||
229 | return r; | ||
230 | } | ||
231 | WREG32(scratch, 0xCAFEDEAD); | ||
232 | r = radeon_ib_get(rdev, &ib); | ||
233 | if (r) { | ||
234 | return r; | ||
235 | } | ||
236 | ib->ptr[0] = PACKET0(scratch, 0); | ||
237 | ib->ptr[1] = 0xDEADBEEF; | ||
238 | ib->ptr[2] = PACKET2(0); | ||
239 | ib->ptr[3] = PACKET2(0); | ||
240 | ib->ptr[4] = PACKET2(0); | ||
241 | ib->ptr[5] = PACKET2(0); | ||
242 | ib->ptr[6] = PACKET2(0); | ||
243 | ib->ptr[7] = PACKET2(0); | ||
244 | ib->length_dw = 8; | ||
245 | r = radeon_ib_schedule(rdev, ib); | ||
246 | if (r) { | ||
247 | radeon_scratch_free(rdev, scratch); | ||
248 | radeon_ib_free(rdev, &ib); | ||
249 | return r; | ||
250 | } | ||
251 | r = radeon_fence_wait(ib->fence, false); | ||
252 | if (r) { | ||
253 | return r; | ||
254 | } | ||
255 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
256 | tmp = RREG32(scratch); | ||
257 | if (tmp == 0xDEADBEEF) { | ||
258 | break; | ||
259 | } | ||
260 | DRM_UDELAY(1); | ||
261 | } | ||
262 | if (i < rdev->usec_timeout) { | ||
263 | DRM_INFO("ib test succeeded in %u usecs\n", i); | ||
264 | } else { | ||
265 | DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", | ||
266 | scratch, tmp); | ||
267 | r = -EINVAL; | ||
268 | } | ||
269 | radeon_scratch_free(rdev, scratch); | ||
270 | radeon_ib_free(rdev, &ib); | ||
271 | return r; | ||
272 | } | ||
273 | |||
274 | 207 | ||
275 | /* | 208 | /* |
276 | * Ring. | 209 | * Ring. |
277 | */ | 210 | */ |
278 | void radeon_ring_free_size(struct radeon_device *rdev) | 211 | void radeon_ring_free_size(struct radeon_device *rdev) |
279 | { | 212 | { |
280 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); | 213 | if (rdev->family >= CHIP_R600) |
214 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); | ||
215 | else | ||
216 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); | ||
281 | /* This works because ring_size is a power of 2 */ | 217 | /* This works because ring_size is a power of 2 */ |
282 | rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4)); | 218 | rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4)); |
283 | rdev->cp.ring_free_dw -= rdev->cp.wptr; | 219 | rdev->cp.ring_free_dw -= rdev->cp.wptr; |
@@ -320,11 +256,10 @@ void radeon_ring_unlock_commit(struct radeon_device *rdev) | |||
320 | count_dw_pad = (rdev->cp.align_mask + 1) - | 256 | count_dw_pad = (rdev->cp.align_mask + 1) - |
321 | (rdev->cp.wptr & rdev->cp.align_mask); | 257 | (rdev->cp.wptr & rdev->cp.align_mask); |
322 | for (i = 0; i < count_dw_pad; i++) { | 258 | for (i = 0; i < count_dw_pad; i++) { |
323 | radeon_ring_write(rdev, PACKET2(0)); | 259 | radeon_ring_write(rdev, 2 << 30); |
324 | } | 260 | } |
325 | DRM_MEMORYBARRIER(); | 261 | DRM_MEMORYBARRIER(); |
326 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); | 262 | radeon_cp_commit(rdev); |
327 | (void)RREG32(RADEON_CP_RB_WPTR); | ||
328 | mutex_unlock(&rdev->cp.mutex); | 263 | mutex_unlock(&rdev->cp.mutex); |
329 | } | 264 | } |
330 | 265 | ||
@@ -334,46 +269,6 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev) | |||
334 | mutex_unlock(&rdev->cp.mutex); | 269 | mutex_unlock(&rdev->cp.mutex); |
335 | } | 270 | } |
336 | 271 | ||
337 | int radeon_ring_test(struct radeon_device *rdev) | ||
338 | { | ||
339 | uint32_t scratch; | ||
340 | uint32_t tmp = 0; | ||
341 | unsigned i; | ||
342 | int r; | ||
343 | |||
344 | r = radeon_scratch_get(rdev, &scratch); | ||
345 | if (r) { | ||
346 | DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); | ||
347 | return r; | ||
348 | } | ||
349 | WREG32(scratch, 0xCAFEDEAD); | ||
350 | r = radeon_ring_lock(rdev, 2); | ||
351 | if (r) { | ||
352 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
353 | radeon_scratch_free(rdev, scratch); | ||
354 | return r; | ||
355 | } | ||
356 | radeon_ring_write(rdev, PACKET0(scratch, 0)); | ||
357 | radeon_ring_write(rdev, 0xDEADBEEF); | ||
358 | radeon_ring_unlock_commit(rdev); | ||
359 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
360 | tmp = RREG32(scratch); | ||
361 | if (tmp == 0xDEADBEEF) { | ||
362 | break; | ||
363 | } | ||
364 | DRM_UDELAY(1); | ||
365 | } | ||
366 | if (i < rdev->usec_timeout) { | ||
367 | DRM_INFO("ring test succeeded in %d usecs\n", i); | ||
368 | } else { | ||
369 | DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n", | ||
370 | scratch, tmp); | ||
371 | r = -EINVAL; | ||
372 | } | ||
373 | radeon_scratch_free(rdev, scratch); | ||
374 | return r; | ||
375 | } | ||
376 | |||
377 | int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) | 272 | int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) |
378 | { | 273 | { |
379 | int r; | 274 | int r; |
diff --git a/drivers/gpu/drm/radeon/radeon_share.h b/drivers/gpu/drm/radeon/radeon_share.h index 63a773578f17..5f9e358ab506 100644 --- a/drivers/gpu/drm/radeon/radeon_share.h +++ b/drivers/gpu/drm/radeon/radeon_share.h | |||
@@ -28,12 +28,89 @@ | |||
28 | #ifndef __RADEON_SHARE_H__ | 28 | #ifndef __RADEON_SHARE_H__ |
29 | #define __RADEON_SHARE_H__ | 29 | #define __RADEON_SHARE_H__ |
30 | 30 | ||
31 | /* Common */ | ||
32 | struct radeon_device; | ||
33 | struct radeon_cs_parser; | ||
34 | int radeon_clocks_init(struct radeon_device *rdev); | ||
35 | void radeon_clocks_fini(struct radeon_device *rdev); | ||
36 | void radeon_scratch_init(struct radeon_device *rdev); | ||
37 | void radeon_surface_init(struct radeon_device *rdev); | ||
38 | int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); | ||
39 | |||
40 | |||
41 | /* R100, RV100, RS100, RV200, RS200, R200, RV250, RS300, RV280 */ | ||
31 | void r100_vram_init_sizes(struct radeon_device *rdev); | 42 | void r100_vram_init_sizes(struct radeon_device *rdev); |
32 | 43 | ||
44 | |||
45 | /* R300, R350, RV350, RV380 */ | ||
46 | struct r300_asic { | ||
47 | const unsigned *reg_safe_bm; | ||
48 | unsigned reg_safe_bm_size; | ||
49 | }; | ||
50 | |||
51 | |||
52 | /* RS690, RS740 */ | ||
33 | void rs690_line_buffer_adjust(struct radeon_device *rdev, | 53 | void rs690_line_buffer_adjust(struct radeon_device *rdev, |
34 | struct drm_display_mode *mode1, | 54 | struct drm_display_mode *mode1, |
35 | struct drm_display_mode *mode2); | 55 | struct drm_display_mode *mode2); |
36 | 56 | ||
57 | |||
58 | /* RV515 */ | ||
37 | void rv515_bandwidth_avivo_update(struct radeon_device *rdev); | 59 | void rv515_bandwidth_avivo_update(struct radeon_device *rdev); |
38 | 60 | ||
61 | |||
62 | /* R600, RV610, RV630, RV620, RV635, RV670, RS780, RS880 */ | ||
63 | bool r600_card_posted(struct radeon_device *rdev); | ||
64 | void r600_cp_stop(struct radeon_device *rdev); | ||
65 | void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); | ||
66 | int r600_cp_resume(struct radeon_device *rdev); | ||
67 | int r600_count_pipe_bits(uint32_t val); | ||
68 | int r600_gart_clear_page(struct radeon_device *rdev, int i); | ||
69 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | ||
70 | void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); | ||
71 | int r600_ib_test(struct radeon_device *rdev); | ||
72 | int r600_ring_test(struct radeon_device *rdev); | ||
73 | int r600_wb_init(struct radeon_device *rdev); | ||
74 | void r600_wb_fini(struct radeon_device *rdev); | ||
75 | void r600_scratch_init(struct radeon_device *rdev); | ||
76 | int r600_blit_init(struct radeon_device *rdev); | ||
77 | void r600_blit_fini(struct radeon_device *rdev); | ||
78 | int r600_cp_init_microcode(struct radeon_device *rdev); | ||
79 | struct r600_asic { | ||
80 | unsigned max_pipes; | ||
81 | unsigned max_tile_pipes; | ||
82 | unsigned max_simds; | ||
83 | unsigned max_backends; | ||
84 | unsigned max_gprs; | ||
85 | unsigned max_threads; | ||
86 | unsigned max_stack_entries; | ||
87 | unsigned max_hw_contexts; | ||
88 | unsigned max_gs_threads; | ||
89 | unsigned sx_max_export_size; | ||
90 | unsigned sx_max_export_pos_size; | ||
91 | unsigned sx_max_export_smx_size; | ||
92 | unsigned sq_num_cf_insts; | ||
93 | }; | ||
94 | |||
95 | /* RV770, RV7300, RV710 */ | ||
96 | struct rv770_asic { | ||
97 | unsigned max_pipes; | ||
98 | unsigned max_tile_pipes; | ||
99 | unsigned max_simds; | ||
100 | unsigned max_backends; | ||
101 | unsigned max_gprs; | ||
102 | unsigned max_threads; | ||
103 | unsigned max_stack_entries; | ||
104 | unsigned max_hw_contexts; | ||
105 | unsigned max_gs_threads; | ||
106 | unsigned sx_max_export_size; | ||
107 | unsigned sx_max_export_pos_size; | ||
108 | unsigned sx_max_export_smx_size; | ||
109 | unsigned sq_num_cf_insts; | ||
110 | unsigned sx_num_of_sets; | ||
111 | unsigned sc_prim_fifo_size; | ||
112 | unsigned sc_hiz_tile_fifo_size; | ||
113 | unsigned sc_earlyz_tile_fifo_fize; | ||
114 | }; | ||
115 | |||
39 | #endif | 116 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 2882f40d5ec5..aad0c6fafcf4 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -1546,7 +1546,7 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev, | |||
1546 | } while (i < nbox); | 1546 | } while (i < nbox); |
1547 | } | 1547 | } |
1548 | 1548 | ||
1549 | static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) | 1549 | void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) |
1550 | { | 1550 | { |
1551 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1551 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1552 | struct drm_radeon_master_private *master_priv = master->driver_priv; | 1552 | struct drm_radeon_master_private *master_priv = master->driver_priv; |
@@ -2213,7 +2213,10 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f | |||
2213 | if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) | 2213 | if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) |
2214 | sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; | 2214 | sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; |
2215 | 2215 | ||
2216 | radeon_cp_dispatch_swap(dev, file_priv->master); | 2216 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
2217 | r600_cp_dispatch_swap(dev, file_priv); | ||
2218 | else | ||
2219 | radeon_cp_dispatch_swap(dev, file_priv->master); | ||
2217 | sarea_priv->ctx_owner = 0; | 2220 | sarea_priv->ctx_owner = 0; |
2218 | 2221 | ||
2219 | COMMIT_RING(); | 2222 | COMMIT_RING(); |
@@ -2412,7 +2415,10 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file | |||
2412 | RING_SPACE_TEST_WITH_RETURN(dev_priv); | 2415 | RING_SPACE_TEST_WITH_RETURN(dev_priv); |
2413 | VB_AGE_TEST_WITH_RETURN(dev_priv); | 2416 | VB_AGE_TEST_WITH_RETURN(dev_priv); |
2414 | 2417 | ||
2415 | ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); | 2418 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
2419 | ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image); | ||
2420 | else | ||
2421 | ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); | ||
2416 | 2422 | ||
2417 | return ret; | 2423 | return ret; |
2418 | } | 2424 | } |
@@ -2495,8 +2501,9 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil | |||
2495 | radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); | 2501 | radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); |
2496 | } | 2502 | } |
2497 | 2503 | ||
2498 | if (indirect->discard) | 2504 | if (indirect->discard) { |
2499 | radeon_cp_discard_buffer(dev, file_priv->master, buf); | 2505 | radeon_cp_discard_buffer(dev, file_priv->master, buf); |
2506 | } | ||
2500 | 2507 | ||
2501 | COMMIT_RING(); | 2508 | COMMIT_RING(); |
2502 | return 0; | 2509 | return 0; |
@@ -3227,7 +3234,8 @@ struct drm_ioctl_desc radeon_ioctls[] = { | |||
3227 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), | 3234 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), |
3228 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), | 3235 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), |
3229 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), | 3236 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), |
3230 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) | 3237 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), |
3238 | DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) | ||
3231 | }; | 3239 | }; |
3232 | 3240 | ||
3233 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); | 3241 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index dc7a44274ea8..acd889c94549 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -376,9 +376,8 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, | |||
376 | radeon_move_null(bo, new_mem); | 376 | radeon_move_null(bo, new_mem); |
377 | return 0; | 377 | return 0; |
378 | } | 378 | } |
379 | if (!rdev->cp.ready) { | 379 | if (!rdev->cp.ready || rdev->asic->copy == NULL) { |
380 | /* use memcpy */ | 380 | /* use memcpy */ |
381 | DRM_ERROR("CP is not ready use memcpy.\n"); | ||
382 | goto memcpy; | 381 | goto memcpy; |
383 | } | 382 | } |
384 | 383 | ||
@@ -495,7 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
495 | return r; | 494 | return r; |
496 | } | 495 | } |
497 | DRM_INFO("radeon: %uM of VRAM memory ready\n", | 496 | DRM_INFO("radeon: %uM of VRAM memory ready\n", |
498 | rdev->mc.real_vram_size / (1024 * 1024)); | 497 | (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); |
499 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0, | 498 | r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0, |
500 | ((rdev->mc.gtt_size) >> PAGE_SHIFT)); | 499 | ((rdev->mc.gtt_size) >> PAGE_SHIFT)); |
501 | if (r) { | 500 | if (r) { |
@@ -503,7 +502,7 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
503 | return r; | 502 | return r; |
504 | } | 503 | } |
505 | DRM_INFO("radeon: %uM of GTT memory ready.\n", | 504 | DRM_INFO("radeon: %uM of GTT memory ready.\n", |
506 | rdev->mc.gtt_size / (1024 * 1024)); | 505 | (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); |
507 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 506 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { |
508 | rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; | 507 | rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; |
509 | } | 508 | } |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index b29affd9c5d8..8c3ea7e36060 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -63,7 +63,7 @@ void rs400_gart_adjust_size(struct radeon_device *rdev) | |||
63 | break; | 63 | break; |
64 | default: | 64 | default: |
65 | DRM_ERROR("Unable to use IGP GART size %uM\n", | 65 | DRM_ERROR("Unable to use IGP GART size %uM\n", |
66 | rdev->mc.gtt_size >> 20); | 66 | (unsigned)(rdev->mc.gtt_size >> 20)); |
67 | DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n"); | 67 | DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n"); |
68 | DRM_ERROR("Forcing to 32M GART size\n"); | 68 | DRM_ERROR("Forcing to 32M GART size\n"); |
69 | rdev->mc.gtt_size = 32 * 1024 * 1024; | 69 | rdev->mc.gtt_size = 32 * 1024 * 1024; |
diff --git a/drivers/gpu/drm/radeon/rs780.c b/drivers/gpu/drm/radeon/rs780.c deleted file mode 100644 index 0affcff81825..000000000000 --- a/drivers/gpu/drm/radeon/rs780.c +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * Copyright 2009 Jerome Glisse. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: Dave Airlie | ||
25 | * Alex Deucher | ||
26 | * Jerome Glisse | ||
27 | */ | ||
28 | #include "drmP.h" | ||
29 | #include "radeon_reg.h" | ||
30 | #include "radeon.h" | ||
31 | |||
32 | /* rs780 depends on : */ | ||
33 | void rs600_mc_disable_clients(struct radeon_device *rdev); | ||
34 | |||
35 | /* This files gather functions specifics to: | ||
36 | * rs780 | ||
37 | * | ||
38 | * Some of these functions might be used by newer ASICs. | ||
39 | */ | ||
40 | int rs780_mc_wait_for_idle(struct radeon_device *rdev); | ||
41 | void rs780_gpu_init(struct radeon_device *rdev); | ||
42 | |||
43 | |||
44 | /* | ||
45 | * MC | ||
46 | */ | ||
47 | int rs780_mc_init(struct radeon_device *rdev) | ||
48 | { | ||
49 | rs780_gpu_init(rdev); | ||
50 | /* FIXME: implement */ | ||
51 | |||
52 | rs600_mc_disable_clients(rdev); | ||
53 | if (rs780_mc_wait_for_idle(rdev)) { | ||
54 | printk(KERN_WARNING "Failed to wait MC idle while " | ||
55 | "programming pipes. Bad things might happen.\n"); | ||
56 | } | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | void rs780_mc_fini(struct radeon_device *rdev) | ||
61 | { | ||
62 | /* FIXME: implement */ | ||
63 | } | ||
64 | |||
65 | |||
66 | /* | ||
67 | * Global GPU functions | ||
68 | */ | ||
69 | void rs780_errata(struct radeon_device *rdev) | ||
70 | { | ||
71 | rdev->pll_errata = 0; | ||
72 | } | ||
73 | |||
74 | int rs780_mc_wait_for_idle(struct radeon_device *rdev) | ||
75 | { | ||
76 | /* FIXME: implement */ | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | void rs780_gpu_init(struct radeon_device *rdev) | ||
81 | { | ||
82 | /* FIXME: implement */ | ||
83 | } | ||
84 | |||
85 | |||
86 | /* | ||
87 | * VRAM info | ||
88 | */ | ||
89 | void rs780_vram_get_type(struct radeon_device *rdev) | ||
90 | { | ||
91 | /* FIXME: implement */ | ||
92 | } | ||
93 | |||
94 | void rs780_vram_info(struct radeon_device *rdev) | ||
95 | { | ||
96 | rs780_vram_get_type(rdev); | ||
97 | |||
98 | /* FIXME: implement */ | ||
99 | /* Could aper size report 0 ? */ | ||
100 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | ||
101 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | ||
102 | } | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 97965c430c1f..99e397f16384 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -27,7 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
29 | #include "drmP.h" | 29 | #include "drmP.h" |
30 | #include "rv515r.h" | 30 | #include "rv515d.h" |
31 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "radeon_share.h" | 32 | #include "radeon_share.h" |
33 | 33 | ||
diff --git a/drivers/gpu/drm/radeon/rv515r.h b/drivers/gpu/drm/radeon/rv515d.h index f3cf84039906..a65e17ec1c08 100644 --- a/drivers/gpu/drm/radeon/rv515r.h +++ b/drivers/gpu/drm/radeon/rv515d.h | |||
@@ -25,10 +25,12 @@ | |||
25 | * Alex Deucher | 25 | * Alex Deucher |
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #ifndef RV515R_H | 28 | #ifndef __RV515D_H__ |
29 | #define RV515R_H | 29 | #define __RV515D_H__ |
30 | 30 | ||
31 | /* RV515 registers */ | 31 | /* |
32 | * RV515 registers | ||
33 | */ | ||
32 | #define PCIE_INDEX 0x0030 | 34 | #define PCIE_INDEX 0x0030 |
33 | #define PCIE_DATA 0x0034 | 35 | #define PCIE_DATA 0x0034 |
34 | #define MC_IND_INDEX 0x0070 | 36 | #define MC_IND_INDEX 0x0070 |
@@ -166,5 +168,53 @@ | |||
166 | #define MC_GLOBW_INIT_LAT_MASK 0xF0000000 | 168 | #define MC_GLOBW_INIT_LAT_MASK 0xF0000000 |
167 | 169 | ||
168 | 170 | ||
171 | /* | ||
172 | * PM4 packet | ||
173 | */ | ||
174 | #define CP_PACKET0 0x00000000 | ||
175 | #define PACKET0_BASE_INDEX_SHIFT 0 | ||
176 | #define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) | ||
177 | #define PACKET0_COUNT_SHIFT 16 | ||
178 | #define PACKET0_COUNT_MASK (0x3fff << 16) | ||
179 | #define CP_PACKET1 0x40000000 | ||
180 | #define CP_PACKET2 0x80000000 | ||
181 | #define PACKET2_PAD_SHIFT 0 | ||
182 | #define PACKET2_PAD_MASK (0x3fffffff << 0) | ||
183 | #define CP_PACKET3 0xC0000000 | ||
184 | #define PACKET3_IT_OPCODE_SHIFT 8 | ||
185 | #define PACKET3_IT_OPCODE_MASK (0xff << 8) | ||
186 | #define PACKET3_COUNT_SHIFT 16 | ||
187 | #define PACKET3_COUNT_MASK (0x3fff << 16) | ||
188 | /* PACKET3 op code */ | ||
189 | #define PACKET3_NOP 0x10 | ||
190 | #define PACKET3_3D_DRAW_VBUF 0x28 | ||
191 | #define PACKET3_3D_DRAW_IMMD 0x29 | ||
192 | #define PACKET3_3D_DRAW_INDX 0x2A | ||
193 | #define PACKET3_3D_LOAD_VBPNTR 0x2F | ||
194 | #define PACKET3_INDX_BUFFER 0x33 | ||
195 | #define PACKET3_3D_DRAW_VBUF_2 0x34 | ||
196 | #define PACKET3_3D_DRAW_IMMD_2 0x35 | ||
197 | #define PACKET3_3D_DRAW_INDX_2 0x36 | ||
198 | #define PACKET3_BITBLT_MULTI 0x9B | ||
199 | |||
200 | #define PACKET0(reg, n) (CP_PACKET0 | \ | ||
201 | REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ | ||
202 | REG_SET(PACKET0_COUNT, (n))) | ||
203 | #define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) | ||
204 | #define PACKET3(op, n) (CP_PACKET3 | \ | ||
205 | REG_SET(PACKET3_IT_OPCODE, (op)) | \ | ||
206 | REG_SET(PACKET3_COUNT, (n))) | ||
207 | |||
208 | #define PACKET_TYPE0 0 | ||
209 | #define PACKET_TYPE1 1 | ||
210 | #define PACKET_TYPE2 2 | ||
211 | #define PACKET_TYPE3 3 | ||
212 | |||
213 | #define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) | ||
214 | #define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) | ||
215 | #define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) | ||
216 | #define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) | ||
217 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | ||
218 | |||
169 | #endif | 219 | #endif |
170 | 220 | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 21d8ffd57308..57765f6d5b20 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -25,100 +25,975 @@ | |||
25 | * Alex Deucher | 25 | * Alex Deucher |
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #include <linux/firmware.h> | ||
29 | #include <linux/platform_device.h> | ||
28 | #include "drmP.h" | 30 | #include "drmP.h" |
29 | #include "radeon_reg.h" | ||
30 | #include "radeon.h" | 31 | #include "radeon.h" |
32 | #include "radeon_share.h" | ||
33 | #include "rv770d.h" | ||
34 | #include "avivod.h" | ||
35 | #include "atom.h" | ||
31 | 36 | ||
32 | /* rv770,rv730,rv710 depends on : */ | 37 | #define R700_PFP_UCODE_SIZE 848 |
33 | void rs600_mc_disable_clients(struct radeon_device *rdev); | 38 | #define R700_PM4_UCODE_SIZE 1360 |
34 | 39 | ||
35 | /* This files gather functions specifics to: | 40 | static void rv770_gpu_init(struct radeon_device *rdev); |
36 | * rv770,rv730,rv710 | 41 | void rv770_fini(struct radeon_device *rdev); |
37 | * | ||
38 | * Some of these functions might be used by newer ASICs. | ||
39 | */ | ||
40 | int rv770_mc_wait_for_idle(struct radeon_device *rdev); | ||
41 | void rv770_gpu_init(struct radeon_device *rdev); | ||
42 | 42 | ||
43 | 43 | ||
44 | /* | 44 | /* |
45 | * MC | 45 | * GART |
46 | */ | 46 | */ |
47 | int rv770_mc_init(struct radeon_device *rdev) | 47 | int rv770_pcie_gart_enable(struct radeon_device *rdev) |
48 | { | 48 | { |
49 | uint32_t tmp; | 49 | u32 tmp; |
50 | int r, i; | ||
50 | 51 | ||
51 | rv770_gpu_init(rdev); | 52 | /* Initialize common gart structure */ |
53 | r = radeon_gart_init(rdev); | ||
54 | if (r) { | ||
55 | return r; | ||
56 | } | ||
57 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; | ||
58 | r = radeon_gart_table_vram_alloc(rdev); | ||
59 | if (r) { | ||
60 | return r; | ||
61 | } | ||
62 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | ||
63 | r600_gart_clear_page(rdev, i); | ||
64 | /* Setup L2 cache */ | ||
65 | WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | | ||
66 | ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | | ||
67 | EFFECTIVE_L2_QUEUE_SIZE(7)); | ||
68 | WREG32(VM_L2_CNTL2, 0); | ||
69 | WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); | ||
70 | /* Setup TLB control */ | ||
71 | tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | | ||
72 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | | ||
73 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | | ||
74 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | ||
75 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
76 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
77 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
78 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | ||
79 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | ||
80 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | ||
81 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | ||
82 | WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); | ||
83 | WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12); | ||
84 | WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); | ||
85 | WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | | ||
86 | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); | ||
87 | WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | ||
88 | (u32)(rdev->dummy_page.addr >> 12)); | ||
89 | for (i = 1; i < 7; i++) | ||
90 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | ||
52 | 91 | ||
53 | /* setup the gart before changing location so we can ask to | 92 | r600_pcie_gart_tlb_flush(rdev); |
54 | * discard unmapped mc request | 93 | rdev->gart.ready = true; |
55 | */ | ||
56 | /* FIXME: disable out of gart access */ | ||
57 | tmp = rdev->mc.gtt_location / 4096; | ||
58 | tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp); | ||
59 | WREG32(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp); | ||
60 | tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096; | ||
61 | tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp); | ||
62 | WREG32(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp); | ||
63 | |||
64 | rs600_mc_disable_clients(rdev); | ||
65 | if (rv770_mc_wait_for_idle(rdev)) { | ||
66 | printk(KERN_WARNING "Failed to wait MC idle while " | ||
67 | "programming pipes. Bad things might happen.\n"); | ||
68 | } | ||
69 | |||
70 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | ||
71 | tmp = REG_SET(R700_MC_FB_TOP, tmp >> 24); | ||
72 | tmp |= REG_SET(R700_MC_FB_BASE, rdev->mc.vram_location >> 24); | ||
73 | WREG32(R700_MC_VM_FB_LOCATION, tmp); | ||
74 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | ||
75 | tmp = REG_SET(R700_MC_AGP_TOP, tmp >> 22); | ||
76 | WREG32(R700_MC_VM_AGP_TOP, tmp); | ||
77 | tmp = REG_SET(R700_MC_AGP_BOT, rdev->mc.gtt_location >> 22); | ||
78 | WREG32(R700_MC_VM_AGP_BOT, tmp); | ||
79 | return 0; | 94 | return 0; |
80 | } | 95 | } |
81 | 96 | ||
82 | void rv770_mc_fini(struct radeon_device *rdev) | 97 | void rv770_pcie_gart_disable(struct radeon_device *rdev) |
83 | { | 98 | { |
84 | /* FIXME: implement */ | 99 | u32 tmp; |
100 | int i; | ||
101 | |||
102 | /* Clear ptes*/ | ||
103 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | ||
104 | r600_gart_clear_page(rdev, i); | ||
105 | r600_pcie_gart_tlb_flush(rdev); | ||
106 | /* Disable all tables */ | ||
107 | for (i = 0; i < 7; i++) | ||
108 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | ||
109 | |||
110 | /* Setup L2 cache */ | ||
111 | WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | | ||
112 | EFFECTIVE_L2_QUEUE_SIZE(7)); | ||
113 | WREG32(VM_L2_CNTL2, 0); | ||
114 | WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); | ||
115 | /* Setup TLB control */ | ||
116 | tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | ||
117 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
118 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
119 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
120 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | ||
121 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | ||
122 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | ||
123 | WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); | ||
85 | } | 124 | } |
86 | 125 | ||
87 | 126 | ||
88 | /* | 127 | /* |
89 | * Global GPU functions | 128 | * MC |
90 | */ | 129 | */ |
91 | void rv770_errata(struct radeon_device *rdev) | 130 | static void rv770_mc_resume(struct radeon_device *rdev) |
92 | { | 131 | { |
93 | rdev->pll_errata = 0; | 132 | u32 d1vga_control, d2vga_control; |
133 | u32 vga_render_control, vga_hdp_control; | ||
134 | u32 d1crtc_control, d2crtc_control; | ||
135 | u32 new_d1grph_primary, new_d1grph_secondary; | ||
136 | u32 new_d2grph_primary, new_d2grph_secondary; | ||
137 | u64 old_vram_start; | ||
138 | u32 tmp; | ||
139 | int i, j; | ||
140 | |||
141 | /* Initialize HDP */ | ||
142 | for (i = 0, j = 0; i < 32; i++, j += 0x18) { | ||
143 | WREG32((0x2c14 + j), 0x00000000); | ||
144 | WREG32((0x2c18 + j), 0x00000000); | ||
145 | WREG32((0x2c1c + j), 0x00000000); | ||
146 | WREG32((0x2c20 + j), 0x00000000); | ||
147 | WREG32((0x2c24 + j), 0x00000000); | ||
148 | } | ||
149 | WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); | ||
150 | |||
151 | d1vga_control = RREG32(D1VGA_CONTROL); | ||
152 | d2vga_control = RREG32(D2VGA_CONTROL); | ||
153 | vga_render_control = RREG32(VGA_RENDER_CONTROL); | ||
154 | vga_hdp_control = RREG32(VGA_HDP_CONTROL); | ||
155 | d1crtc_control = RREG32(D1CRTC_CONTROL); | ||
156 | d2crtc_control = RREG32(D2CRTC_CONTROL); | ||
157 | old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | ||
158 | new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS); | ||
159 | new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS); | ||
160 | new_d1grph_primary += rdev->mc.vram_start - old_vram_start; | ||
161 | new_d1grph_secondary += rdev->mc.vram_start - old_vram_start; | ||
162 | new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS); | ||
163 | new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS); | ||
164 | new_d2grph_primary += rdev->mc.vram_start - old_vram_start; | ||
165 | new_d2grph_secondary += rdev->mc.vram_start - old_vram_start; | ||
166 | |||
167 | /* Stop all video */ | ||
168 | WREG32(D1VGA_CONTROL, 0); | ||
169 | WREG32(D2VGA_CONTROL, 0); | ||
170 | WREG32(VGA_RENDER_CONTROL, 0); | ||
171 | WREG32(D1CRTC_UPDATE_LOCK, 1); | ||
172 | WREG32(D2CRTC_UPDATE_LOCK, 1); | ||
173 | WREG32(D1CRTC_CONTROL, 0); | ||
174 | WREG32(D2CRTC_CONTROL, 0); | ||
175 | WREG32(D1CRTC_UPDATE_LOCK, 0); | ||
176 | WREG32(D2CRTC_UPDATE_LOCK, 0); | ||
177 | |||
178 | mdelay(1); | ||
179 | if (r600_mc_wait_for_idle(rdev)) { | ||
180 | printk(KERN_WARNING "[drm] MC not idle !\n"); | ||
181 | } | ||
182 | |||
183 | /* Lockout access through VGA aperture*/ | ||
184 | WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); | ||
185 | |||
186 | /* Update configuration */ | ||
187 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); | ||
188 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); | ||
189 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | ||
190 | tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16; | ||
191 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | ||
192 | WREG32(MC_VM_FB_LOCATION, tmp); | ||
193 | WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); | ||
194 | WREG32(HDP_NONSURFACE_INFO, (2 << 7)); | ||
195 | WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); | ||
196 | if (rdev->flags & RADEON_IS_AGP) { | ||
197 | WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16); | ||
198 | WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); | ||
199 | WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); | ||
200 | } else { | ||
201 | WREG32(MC_VM_AGP_BASE, 0); | ||
202 | WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); | ||
203 | WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); | ||
204 | } | ||
205 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary); | ||
206 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary); | ||
207 | WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary); | ||
208 | WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary); | ||
209 | WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); | ||
210 | |||
211 | /* Unlock host access */ | ||
212 | WREG32(VGA_HDP_CONTROL, vga_hdp_control); | ||
213 | |||
214 | mdelay(1); | ||
215 | if (r600_mc_wait_for_idle(rdev)) { | ||
216 | printk(KERN_WARNING "[drm] MC not idle !\n"); | ||
217 | } | ||
218 | |||
219 | /* Restore video state */ | ||
220 | WREG32(D1CRTC_UPDATE_LOCK, 1); | ||
221 | WREG32(D2CRTC_UPDATE_LOCK, 1); | ||
222 | WREG32(D1CRTC_CONTROL, d1crtc_control); | ||
223 | WREG32(D2CRTC_CONTROL, d2crtc_control); | ||
224 | WREG32(D1CRTC_UPDATE_LOCK, 0); | ||
225 | WREG32(D2CRTC_UPDATE_LOCK, 0); | ||
226 | WREG32(D1VGA_CONTROL, d1vga_control); | ||
227 | WREG32(D2VGA_CONTROL, d2vga_control); | ||
228 | WREG32(VGA_RENDER_CONTROL, vga_render_control); | ||
94 | } | 229 | } |
95 | 230 | ||
96 | int rv770_mc_wait_for_idle(struct radeon_device *rdev) | 231 | |
232 | /* | ||
233 | * CP. | ||
234 | */ | ||
235 | void r700_cp_stop(struct radeon_device *rdev) | ||
97 | { | 236 | { |
98 | /* FIXME: implement */ | 237 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); |
99 | return 0; | ||
100 | } | 238 | } |
101 | 239 | ||
102 | void rv770_gpu_init(struct radeon_device *rdev) | 240 | |
241 | static int rv770_cp_load_microcode(struct radeon_device *rdev) | ||
103 | { | 242 | { |
104 | /* FIXME: implement */ | 243 | const __be32 *fw_data; |
244 | int i; | ||
245 | |||
246 | if (!rdev->me_fw || !rdev->pfp_fw) | ||
247 | return -EINVAL; | ||
248 | |||
249 | r700_cp_stop(rdev); | ||
250 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); | ||
251 | |||
252 | /* Reset cp */ | ||
253 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); | ||
254 | RREG32(GRBM_SOFT_RESET); | ||
255 | mdelay(15); | ||
256 | WREG32(GRBM_SOFT_RESET, 0); | ||
257 | |||
258 | fw_data = (const __be32 *)rdev->pfp_fw->data; | ||
259 | WREG32(CP_PFP_UCODE_ADDR, 0); | ||
260 | for (i = 0; i < R700_PFP_UCODE_SIZE; i++) | ||
261 | WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); | ||
262 | WREG32(CP_PFP_UCODE_ADDR, 0); | ||
263 | |||
264 | fw_data = (const __be32 *)rdev->me_fw->data; | ||
265 | WREG32(CP_ME_RAM_WADDR, 0); | ||
266 | for (i = 0; i < R700_PM4_UCODE_SIZE; i++) | ||
267 | WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); | ||
268 | |||
269 | WREG32(CP_PFP_UCODE_ADDR, 0); | ||
270 | WREG32(CP_ME_RAM_WADDR, 0); | ||
271 | WREG32(CP_ME_RAM_RADDR, 0); | ||
272 | return 0; | ||
105 | } | 273 | } |
106 | 274 | ||
107 | 275 | ||
108 | /* | 276 | /* |
109 | * VRAM info | 277 | * Core functions |
110 | */ | 278 | */ |
111 | void rv770_vram_get_type(struct radeon_device *rdev) | 279 | static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, |
280 | u32 num_backends, | ||
281 | u32 backend_disable_mask) | ||
112 | { | 282 | { |
113 | /* FIXME: implement */ | 283 | u32 backend_map = 0; |
284 | u32 enabled_backends_mask; | ||
285 | u32 enabled_backends_count; | ||
286 | u32 cur_pipe; | ||
287 | u32 swizzle_pipe[R7XX_MAX_PIPES]; | ||
288 | u32 cur_backend; | ||
289 | u32 i; | ||
290 | |||
291 | if (num_tile_pipes > R7XX_MAX_PIPES) | ||
292 | num_tile_pipes = R7XX_MAX_PIPES; | ||
293 | if (num_tile_pipes < 1) | ||
294 | num_tile_pipes = 1; | ||
295 | if (num_backends > R7XX_MAX_BACKENDS) | ||
296 | num_backends = R7XX_MAX_BACKENDS; | ||
297 | if (num_backends < 1) | ||
298 | num_backends = 1; | ||
299 | |||
300 | enabled_backends_mask = 0; | ||
301 | enabled_backends_count = 0; | ||
302 | for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { | ||
303 | if (((backend_disable_mask >> i) & 1) == 0) { | ||
304 | enabled_backends_mask |= (1 << i); | ||
305 | ++enabled_backends_count; | ||
306 | } | ||
307 | if (enabled_backends_count == num_backends) | ||
308 | break; | ||
309 | } | ||
310 | |||
311 | if (enabled_backends_count == 0) { | ||
312 | enabled_backends_mask = 1; | ||
313 | enabled_backends_count = 1; | ||
314 | } | ||
315 | |||
316 | if (enabled_backends_count != num_backends) | ||
317 | num_backends = enabled_backends_count; | ||
318 | |||
319 | memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); | ||
320 | switch (num_tile_pipes) { | ||
321 | case 1: | ||
322 | swizzle_pipe[0] = 0; | ||
323 | break; | ||
324 | case 2: | ||
325 | swizzle_pipe[0] = 0; | ||
326 | swizzle_pipe[1] = 1; | ||
327 | break; | ||
328 | case 3: | ||
329 | swizzle_pipe[0] = 0; | ||
330 | swizzle_pipe[1] = 2; | ||
331 | swizzle_pipe[2] = 1; | ||
332 | break; | ||
333 | case 4: | ||
334 | swizzle_pipe[0] = 0; | ||
335 | swizzle_pipe[1] = 2; | ||
336 | swizzle_pipe[2] = 3; | ||
337 | swizzle_pipe[3] = 1; | ||
338 | break; | ||
339 | case 5: | ||
340 | swizzle_pipe[0] = 0; | ||
341 | swizzle_pipe[1] = 2; | ||
342 | swizzle_pipe[2] = 4; | ||
343 | swizzle_pipe[3] = 1; | ||
344 | swizzle_pipe[4] = 3; | ||
345 | break; | ||
346 | case 6: | ||
347 | swizzle_pipe[0] = 0; | ||
348 | swizzle_pipe[1] = 2; | ||
349 | swizzle_pipe[2] = 4; | ||
350 | swizzle_pipe[3] = 5; | ||
351 | swizzle_pipe[4] = 3; | ||
352 | swizzle_pipe[5] = 1; | ||
353 | break; | ||
354 | case 7: | ||
355 | swizzle_pipe[0] = 0; | ||
356 | swizzle_pipe[1] = 2; | ||
357 | swizzle_pipe[2] = 4; | ||
358 | swizzle_pipe[3] = 6; | ||
359 | swizzle_pipe[4] = 3; | ||
360 | swizzle_pipe[5] = 1; | ||
361 | swizzle_pipe[6] = 5; | ||
362 | break; | ||
363 | case 8: | ||
364 | swizzle_pipe[0] = 0; | ||
365 | swizzle_pipe[1] = 2; | ||
366 | swizzle_pipe[2] = 4; | ||
367 | swizzle_pipe[3] = 6; | ||
368 | swizzle_pipe[4] = 3; | ||
369 | swizzle_pipe[5] = 1; | ||
370 | swizzle_pipe[6] = 7; | ||
371 | swizzle_pipe[7] = 5; | ||
372 | break; | ||
373 | } | ||
374 | |||
375 | cur_backend = 0; | ||
376 | for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { | ||
377 | while (((1 << cur_backend) & enabled_backends_mask) == 0) | ||
378 | cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; | ||
379 | |||
380 | backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); | ||
381 | |||
382 | cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; | ||
383 | } | ||
384 | |||
385 | return backend_map; | ||
114 | } | 386 | } |
115 | 387 | ||
116 | void rv770_vram_info(struct radeon_device *rdev) | 388 | static void rv770_gpu_init(struct radeon_device *rdev) |
117 | { | 389 | { |
118 | rv770_vram_get_type(rdev); | 390 | int i, j, num_qd_pipes; |
391 | u32 sx_debug_1; | ||
392 | u32 smx_dc_ctl0; | ||
393 | u32 num_gs_verts_per_thread; | ||
394 | u32 vgt_gs_per_es; | ||
395 | u32 gs_prim_buffer_depth = 0; | ||
396 | u32 sq_ms_fifo_sizes; | ||
397 | u32 sq_config; | ||
398 | u32 sq_thread_resource_mgmt; | ||
399 | u32 hdp_host_path_cntl; | ||
400 | u32 sq_dyn_gpr_size_simd_ab_0; | ||
401 | u32 backend_map; | ||
402 | u32 gb_tiling_config = 0; | ||
403 | u32 cc_rb_backend_disable = 0; | ||
404 | u32 cc_gc_shader_pipe_config = 0; | ||
405 | u32 mc_arb_ramcfg; | ||
406 | u32 db_debug4; | ||
119 | 407 | ||
120 | /* FIXME: implement */ | 408 | /* setup chip specs */ |
409 | switch (rdev->family) { | ||
410 | case CHIP_RV770: | ||
411 | rdev->config.rv770.max_pipes = 4; | ||
412 | rdev->config.rv770.max_tile_pipes = 8; | ||
413 | rdev->config.rv770.max_simds = 10; | ||
414 | rdev->config.rv770.max_backends = 4; | ||
415 | rdev->config.rv770.max_gprs = 256; | ||
416 | rdev->config.rv770.max_threads = 248; | ||
417 | rdev->config.rv770.max_stack_entries = 512; | ||
418 | rdev->config.rv770.max_hw_contexts = 8; | ||
419 | rdev->config.rv770.max_gs_threads = 16 * 2; | ||
420 | rdev->config.rv770.sx_max_export_size = 128; | ||
421 | rdev->config.rv770.sx_max_export_pos_size = 16; | ||
422 | rdev->config.rv770.sx_max_export_smx_size = 112; | ||
423 | rdev->config.rv770.sq_num_cf_insts = 2; | ||
424 | |||
425 | rdev->config.rv770.sx_num_of_sets = 7; | ||
426 | rdev->config.rv770.sc_prim_fifo_size = 0xF9; | ||
427 | rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; | ||
428 | rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; | ||
429 | break; | ||
430 | case CHIP_RV730: | ||
431 | rdev->config.rv770.max_pipes = 2; | ||
432 | rdev->config.rv770.max_tile_pipes = 4; | ||
433 | rdev->config.rv770.max_simds = 8; | ||
434 | rdev->config.rv770.max_backends = 2; | ||
435 | rdev->config.rv770.max_gprs = 128; | ||
436 | rdev->config.rv770.max_threads = 248; | ||
437 | rdev->config.rv770.max_stack_entries = 256; | ||
438 | rdev->config.rv770.max_hw_contexts = 8; | ||
439 | rdev->config.rv770.max_gs_threads = 16 * 2; | ||
440 | rdev->config.rv770.sx_max_export_size = 256; | ||
441 | rdev->config.rv770.sx_max_export_pos_size = 32; | ||
442 | rdev->config.rv770.sx_max_export_smx_size = 224; | ||
443 | rdev->config.rv770.sq_num_cf_insts = 2; | ||
444 | |||
445 | rdev->config.rv770.sx_num_of_sets = 7; | ||
446 | rdev->config.rv770.sc_prim_fifo_size = 0xf9; | ||
447 | rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; | ||
448 | rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; | ||
449 | if (rdev->config.rv770.sx_max_export_pos_size > 16) { | ||
450 | rdev->config.rv770.sx_max_export_pos_size -= 16; | ||
451 | rdev->config.rv770.sx_max_export_smx_size += 16; | ||
452 | } | ||
453 | break; | ||
454 | case CHIP_RV710: | ||
455 | rdev->config.rv770.max_pipes = 2; | ||
456 | rdev->config.rv770.max_tile_pipes = 2; | ||
457 | rdev->config.rv770.max_simds = 2; | ||
458 | rdev->config.rv770.max_backends = 1; | ||
459 | rdev->config.rv770.max_gprs = 256; | ||
460 | rdev->config.rv770.max_threads = 192; | ||
461 | rdev->config.rv770.max_stack_entries = 256; | ||
462 | rdev->config.rv770.max_hw_contexts = 4; | ||
463 | rdev->config.rv770.max_gs_threads = 8 * 2; | ||
464 | rdev->config.rv770.sx_max_export_size = 128; | ||
465 | rdev->config.rv770.sx_max_export_pos_size = 16; | ||
466 | rdev->config.rv770.sx_max_export_smx_size = 112; | ||
467 | rdev->config.rv770.sq_num_cf_insts = 1; | ||
468 | |||
469 | rdev->config.rv770.sx_num_of_sets = 7; | ||
470 | rdev->config.rv770.sc_prim_fifo_size = 0x40; | ||
471 | rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; | ||
472 | rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; | ||
473 | break; | ||
474 | case CHIP_RV740: | ||
475 | rdev->config.rv770.max_pipes = 4; | ||
476 | rdev->config.rv770.max_tile_pipes = 4; | ||
477 | rdev->config.rv770.max_simds = 8; | ||
478 | rdev->config.rv770.max_backends = 4; | ||
479 | rdev->config.rv770.max_gprs = 256; | ||
480 | rdev->config.rv770.max_threads = 248; | ||
481 | rdev->config.rv770.max_stack_entries = 512; | ||
482 | rdev->config.rv770.max_hw_contexts = 8; | ||
483 | rdev->config.rv770.max_gs_threads = 16 * 2; | ||
484 | rdev->config.rv770.sx_max_export_size = 256; | ||
485 | rdev->config.rv770.sx_max_export_pos_size = 32; | ||
486 | rdev->config.rv770.sx_max_export_smx_size = 224; | ||
487 | rdev->config.rv770.sq_num_cf_insts = 2; | ||
488 | |||
489 | rdev->config.rv770.sx_num_of_sets = 7; | ||
490 | rdev->config.rv770.sc_prim_fifo_size = 0x100; | ||
491 | rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; | ||
492 | rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; | ||
493 | |||
494 | if (rdev->config.rv770.sx_max_export_pos_size > 16) { | ||
495 | rdev->config.rv770.sx_max_export_pos_size -= 16; | ||
496 | rdev->config.rv770.sx_max_export_smx_size += 16; | ||
497 | } | ||
498 | break; | ||
499 | default: | ||
500 | break; | ||
501 | } | ||
502 | |||
503 | /* Initialize HDP */ | ||
504 | j = 0; | ||
505 | for (i = 0; i < 32; i++) { | ||
506 | WREG32((0x2c14 + j), 0x00000000); | ||
507 | WREG32((0x2c18 + j), 0x00000000); | ||
508 | WREG32((0x2c1c + j), 0x00000000); | ||
509 | WREG32((0x2c20 + j), 0x00000000); | ||
510 | WREG32((0x2c24 + j), 0x00000000); | ||
511 | j += 0x18; | ||
512 | } | ||
513 | |||
514 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); | ||
515 | |||
516 | /* setup tiling, simd, pipe config */ | ||
517 | mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); | ||
518 | |||
519 | switch (rdev->config.rv770.max_tile_pipes) { | ||
520 | case 1: | ||
521 | gb_tiling_config |= PIPE_TILING(0); | ||
522 | break; | ||
523 | case 2: | ||
524 | gb_tiling_config |= PIPE_TILING(1); | ||
525 | break; | ||
526 | case 4: | ||
527 | gb_tiling_config |= PIPE_TILING(2); | ||
528 | break; | ||
529 | case 8: | ||
530 | gb_tiling_config |= PIPE_TILING(3); | ||
531 | break; | ||
532 | default: | ||
533 | break; | ||
534 | } | ||
535 | |||
536 | if (rdev->family == CHIP_RV770) | ||
537 | gb_tiling_config |= BANK_TILING(1); | ||
538 | else | ||
539 | gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK); | ||
540 | |||
541 | gb_tiling_config |= GROUP_SIZE(0); | ||
542 | |||
543 | if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) { | ||
544 | gb_tiling_config |= ROW_TILING(3); | ||
545 | gb_tiling_config |= SAMPLE_SPLIT(3); | ||
546 | } else { | ||
547 | gb_tiling_config |= | ||
548 | ROW_TILING(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT)); | ||
549 | gb_tiling_config |= | ||
550 | SAMPLE_SPLIT(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT)); | ||
551 | } | ||
552 | |||
553 | gb_tiling_config |= BANK_SWAPS(1); | ||
554 | |||
555 | backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, | ||
556 | rdev->config.rv770.max_backends, | ||
557 | (0xff << rdev->config.rv770.max_backends) & 0xff); | ||
558 | gb_tiling_config |= BACKEND_MAP(backend_map); | ||
559 | |||
560 | cc_gc_shader_pipe_config = | ||
561 | INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK); | ||
562 | cc_gc_shader_pipe_config |= | ||
563 | INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK); | ||
564 | |||
565 | cc_rb_backend_disable = | ||
566 | BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK); | ||
567 | |||
568 | WREG32(GB_TILING_CONFIG, gb_tiling_config); | ||
569 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | ||
570 | WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | ||
571 | |||
572 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); | ||
573 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | ||
574 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | ||
575 | |||
576 | WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); | ||
577 | WREG32(CGTS_SYS_TCC_DISABLE, 0); | ||
578 | WREG32(CGTS_TCC_DISABLE, 0); | ||
579 | WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); | ||
580 | WREG32(CGTS_USER_TCC_DISABLE, 0); | ||
581 | |||
582 | num_qd_pipes = | ||
583 | R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK); | ||
584 | WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK); | ||
585 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK); | ||
586 | |||
587 | /* set HW defaults for 3D engine */ | ||
588 | WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | | ||
589 | ROQ_IB2_START(0x2b))); | ||
590 | |||
591 | WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); | ||
592 | |||
593 | WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | | ||
594 | SYNC_GRADIENT | | ||
595 | SYNC_WALKER | | ||
596 | SYNC_ALIGNER)); | ||
597 | |||
598 | sx_debug_1 = RREG32(SX_DEBUG_1); | ||
599 | sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; | ||
600 | WREG32(SX_DEBUG_1, sx_debug_1); | ||
601 | |||
602 | smx_dc_ctl0 = RREG32(SMX_DC_CTL0); | ||
603 | smx_dc_ctl0 &= ~CACHE_DEPTH(0x1ff); | ||
604 | smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1); | ||
605 | WREG32(SMX_DC_CTL0, smx_dc_ctl0); | ||
606 | |||
607 | WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | | ||
608 | GS_FLUSH_CTL(4) | | ||
609 | ACK_FLUSH_CTL(3) | | ||
610 | SYNC_FLUSH_CTL)); | ||
611 | |||
612 | if (rdev->family == CHIP_RV770) | ||
613 | WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f)); | ||
614 | else { | ||
615 | db_debug4 = RREG32(DB_DEBUG4); | ||
616 | db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER; | ||
617 | WREG32(DB_DEBUG4, db_debug4); | ||
618 | } | ||
619 | |||
620 | WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) | | ||
621 | POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) | | ||
622 | SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1))); | ||
623 | |||
624 | WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) | | ||
625 | SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) | | ||
626 | SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize))); | ||
627 | |||
628 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); | ||
629 | |||
630 | WREG32(VGT_NUM_INSTANCES, 1); | ||
631 | |||
632 | WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0)); | ||
633 | |||
634 | WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); | ||
635 | |||
636 | WREG32(CP_PERFMON_CNTL, 0); | ||
637 | |||
638 | sq_ms_fifo_sizes = (CACHE_FIFO_SIZE(16 * rdev->config.rv770.sq_num_cf_insts) | | ||
639 | DONE_FIFO_HIWATER(0xe0) | | ||
640 | ALU_UPDATE_FIFO_HIWATER(0x8)); | ||
641 | switch (rdev->family) { | ||
642 | case CHIP_RV770: | ||
643 | sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1); | ||
644 | break; | ||
645 | case CHIP_RV730: | ||
646 | case CHIP_RV710: | ||
647 | case CHIP_RV740: | ||
648 | default: | ||
649 | sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4); | ||
650 | break; | ||
651 | } | ||
652 | WREG32(SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); | ||
653 | |||
654 | /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT | ||
655 | * should be adjusted as needed by the 2D/3D drivers. This just sets default values | ||
656 | */ | ||
657 | sq_config = RREG32(SQ_CONFIG); | ||
658 | sq_config &= ~(PS_PRIO(3) | | ||
659 | VS_PRIO(3) | | ||
660 | GS_PRIO(3) | | ||
661 | ES_PRIO(3)); | ||
662 | sq_config |= (DX9_CONSTS | | ||
663 | VC_ENABLE | | ||
664 | EXPORT_SRC_C | | ||
665 | PS_PRIO(0) | | ||
666 | VS_PRIO(1) | | ||
667 | GS_PRIO(2) | | ||
668 | ES_PRIO(3)); | ||
669 | if (rdev->family == CHIP_RV710) | ||
670 | /* no vertex cache */ | ||
671 | sq_config &= ~VC_ENABLE; | ||
672 | |||
673 | WREG32(SQ_CONFIG, sq_config); | ||
674 | |||
675 | WREG32(SQ_GPR_RESOURCE_MGMT_1, (NUM_PS_GPRS((rdev->config.rv770.max_gprs * 24)/64) | | ||
676 | NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) | | ||
677 | NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2))); | ||
678 | |||
679 | WREG32(SQ_GPR_RESOURCE_MGMT_2, (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) | | ||
680 | NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64))); | ||
681 | |||
682 | sq_thread_resource_mgmt = (NUM_PS_THREADS((rdev->config.rv770.max_threads * 4)/8) | | ||
683 | NUM_VS_THREADS((rdev->config.rv770.max_threads * 2)/8) | | ||
684 | NUM_ES_THREADS((rdev->config.rv770.max_threads * 1)/8)); | ||
685 | if (((rdev->config.rv770.max_threads * 1) / 8) > rdev->config.rv770.max_gs_threads) | ||
686 | sq_thread_resource_mgmt |= NUM_GS_THREADS(rdev->config.rv770.max_gs_threads); | ||
687 | else | ||
688 | sq_thread_resource_mgmt |= NUM_GS_THREADS((rdev->config.rv770.max_gs_threads * 1)/8); | ||
689 | WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); | ||
690 | |||
691 | WREG32(SQ_STACK_RESOURCE_MGMT_1, (NUM_PS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) | | ||
692 | NUM_VS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4))); | ||
693 | |||
694 | WREG32(SQ_STACK_RESOURCE_MGMT_2, (NUM_GS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) | | ||
695 | NUM_ES_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4))); | ||
696 | |||
697 | sq_dyn_gpr_size_simd_ab_0 = (SIMDA_RING0((rdev->config.rv770.max_gprs * 38)/64) | | ||
698 | SIMDA_RING1((rdev->config.rv770.max_gprs * 38)/64) | | ||
699 | SIMDB_RING0((rdev->config.rv770.max_gprs * 38)/64) | | ||
700 | SIMDB_RING1((rdev->config.rv770.max_gprs * 38)/64)); | ||
701 | |||
702 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); | ||
703 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); | ||
704 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); | ||
705 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); | ||
706 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); | ||
707 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); | ||
708 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); | ||
709 | WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); | ||
710 | |||
711 | WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | | ||
712 | FORCE_EOV_MAX_REZ_CNT(255))); | ||
713 | |||
714 | if (rdev->family == CHIP_RV710) | ||
715 | WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) | | ||
716 | AUTO_INVLD_EN(ES_AND_GS_AUTO))); | ||
717 | else | ||
718 | WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) | | ||
719 | AUTO_INVLD_EN(ES_AND_GS_AUTO))); | ||
720 | |||
721 | switch (rdev->family) { | ||
722 | case CHIP_RV770: | ||
723 | case CHIP_RV730: | ||
724 | case CHIP_RV740: | ||
725 | gs_prim_buffer_depth = 384; | ||
726 | break; | ||
727 | case CHIP_RV710: | ||
728 | gs_prim_buffer_depth = 128; | ||
729 | break; | ||
730 | default: | ||
731 | break; | ||
732 | } | ||
733 | |||
734 | num_gs_verts_per_thread = rdev->config.rv770.max_pipes * 16; | ||
735 | vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; | ||
736 | /* Max value for this is 256 */ | ||
737 | if (vgt_gs_per_es > 256) | ||
738 | vgt_gs_per_es = 256; | ||
739 | |||
740 | WREG32(VGT_ES_PER_GS, 128); | ||
741 | WREG32(VGT_GS_PER_ES, vgt_gs_per_es); | ||
742 | WREG32(VGT_GS_PER_VS, 2); | ||
743 | |||
744 | /* more default values. 2D/3D driver should adjust as needed */ | ||
745 | WREG32(VGT_GS_VERTEX_REUSE, 16); | ||
746 | WREG32(PA_SC_LINE_STIPPLE_STATE, 0); | ||
747 | WREG32(VGT_STRMOUT_EN, 0); | ||
748 | WREG32(SX_MISC, 0); | ||
749 | WREG32(PA_SC_MODE_CNTL, 0); | ||
750 | WREG32(PA_SC_EDGERULE, 0xaaaaaaaa); | ||
751 | WREG32(PA_SC_AA_CONFIG, 0); | ||
752 | WREG32(PA_SC_CLIPRECT_RULE, 0xffff); | ||
753 | WREG32(PA_SC_LINE_STIPPLE, 0); | ||
754 | WREG32(SPI_INPUT_Z, 0); | ||
755 | WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2)); | ||
756 | WREG32(CB_COLOR7_FRAG, 0); | ||
757 | |||
758 | /* clear render buffer base addresses */ | ||
759 | WREG32(CB_COLOR0_BASE, 0); | ||
760 | WREG32(CB_COLOR1_BASE, 0); | ||
761 | WREG32(CB_COLOR2_BASE, 0); | ||
762 | WREG32(CB_COLOR3_BASE, 0); | ||
763 | WREG32(CB_COLOR4_BASE, 0); | ||
764 | WREG32(CB_COLOR5_BASE, 0); | ||
765 | WREG32(CB_COLOR6_BASE, 0); | ||
766 | WREG32(CB_COLOR7_BASE, 0); | ||
767 | |||
768 | WREG32(TCP_CNTL, 0); | ||
769 | |||
770 | hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); | ||
771 | WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); | ||
772 | |||
773 | WREG32(PA_SC_MULTI_CHIP_CNTL, 0); | ||
774 | |||
775 | WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | | ||
776 | NUM_CLIP_SEQ(3))); | ||
777 | |||
778 | } | ||
779 | |||
780 | int rv770_mc_init(struct radeon_device *rdev) | ||
781 | { | ||
782 | fixed20_12 a; | ||
783 | u32 tmp; | ||
784 | int r; | ||
785 | |||
786 | /* Get VRAM informations */ | ||
787 | /* FIXME: Don't know how to determine vram width, need to check | ||
788 | * vram_width usage | ||
789 | */ | ||
790 | rdev->mc.vram_width = 128; | ||
791 | rdev->mc.vram_is_ddr = true; | ||
121 | /* Could aper size report 0 ? */ | 792 | /* Could aper size report 0 ? */ |
122 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 793 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
123 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 794 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
795 | /* Setup GPU memory space */ | ||
796 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | ||
797 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | ||
798 | if (rdev->flags & RADEON_IS_AGP) { | ||
799 | r = radeon_agp_init(rdev); | ||
800 | if (r) | ||
801 | return r; | ||
802 | /* gtt_size is setup by radeon_agp_init */ | ||
803 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
804 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; | ||
805 | /* Try to put vram before or after AGP because we | ||
806 | * we want SYSTEM_APERTURE to cover both VRAM and | ||
807 | * AGP so that GPU can catch out of VRAM/AGP access | ||
808 | */ | ||
809 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { | ||
810 | /* Enought place before */ | ||
811 | rdev->mc.vram_location = rdev->mc.gtt_location - | ||
812 | rdev->mc.mc_vram_size; | ||
813 | } else if (tmp > rdev->mc.mc_vram_size) { | ||
814 | /* Enought place after */ | ||
815 | rdev->mc.vram_location = rdev->mc.gtt_location + | ||
816 | rdev->mc.gtt_size; | ||
817 | } else { | ||
818 | /* Try to setup VRAM then AGP might not | ||
819 | * not work on some card | ||
820 | */ | ||
821 | rdev->mc.vram_location = 0x00000000UL; | ||
822 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
823 | } | ||
824 | } else { | ||
825 | rdev->mc.vram_location = 0x00000000UL; | ||
826 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
827 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
828 | } | ||
829 | rdev->mc.vram_start = rdev->mc.vram_location; | ||
830 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size; | ||
831 | rdev->mc.gtt_start = rdev->mc.gtt_location; | ||
832 | rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size; | ||
833 | /* FIXME: we should enforce default clock in case GPU is not in | ||
834 | * default setup | ||
835 | */ | ||
836 | a.full = rfixed_const(100); | ||
837 | rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); | ||
838 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); | ||
839 | return 0; | ||
840 | } | ||
841 | int rv770_gpu_reset(struct radeon_device *rdev) | ||
842 | { | ||
843 | /* FIXME: implement */ | ||
844 | return 0; | ||
845 | } | ||
846 | |||
847 | int rv770_resume(struct radeon_device *rdev) | ||
848 | { | ||
849 | int r; | ||
850 | |||
851 | rv770_mc_resume(rdev); | ||
852 | r = rv770_pcie_gart_enable(rdev); | ||
853 | if (r) | ||
854 | return r; | ||
855 | rv770_gpu_init(rdev); | ||
856 | r = radeon_ring_init(rdev, rdev->cp.ring_size); | ||
857 | if (r) | ||
858 | return r; | ||
859 | r = rv770_cp_load_microcode(rdev); | ||
860 | if (r) | ||
861 | return r; | ||
862 | r = r600_cp_resume(rdev); | ||
863 | if (r) | ||
864 | return r; | ||
865 | r = r600_wb_init(rdev); | ||
866 | if (r) | ||
867 | return r; | ||
868 | return 0; | ||
869 | } | ||
870 | |||
871 | int rv770_suspend(struct radeon_device *rdev) | ||
872 | { | ||
873 | /* FIXME: we should wait for ring to be empty */ | ||
874 | r700_cp_stop(rdev); | ||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | /* Plan is to move initialization in that function and use | ||
879 | * helper function so that radeon_device_init pretty much | ||
880 | * do nothing more than calling asic specific function. This | ||
881 | * should also allow to remove a bunch of callback function | ||
882 | * like vram_info. | ||
883 | */ | ||
884 | int rv770_init(struct radeon_device *rdev) | ||
885 | { | ||
886 | int r; | ||
887 | |||
888 | rdev->new_init_path = true; | ||
889 | r = radeon_dummy_page_init(rdev); | ||
890 | if (r) | ||
891 | return r; | ||
892 | /* This don't do much */ | ||
893 | r = radeon_gem_init(rdev); | ||
894 | if (r) | ||
895 | return r; | ||
896 | /* Read BIOS */ | ||
897 | if (!radeon_get_bios(rdev)) { | ||
898 | if (ASIC_IS_AVIVO(rdev)) | ||
899 | return -EINVAL; | ||
900 | } | ||
901 | /* Must be an ATOMBIOS */ | ||
902 | if (!rdev->is_atom_bios) | ||
903 | return -EINVAL; | ||
904 | r = radeon_atombios_init(rdev); | ||
905 | if (r) | ||
906 | return r; | ||
907 | /* Post card if necessary */ | ||
908 | if (!r600_card_posted(rdev) && rdev->bios) { | ||
909 | DRM_INFO("GPU not posted. posting now...\n"); | ||
910 | atom_asic_init(rdev->mode_info.atom_context); | ||
911 | } | ||
912 | /* Initialize scratch registers */ | ||
913 | r600_scratch_init(rdev); | ||
914 | /* Initialize surface registers */ | ||
915 | radeon_surface_init(rdev); | ||
916 | r = radeon_clocks_init(rdev); | ||
917 | if (r) | ||
918 | return r; | ||
919 | /* Fence driver */ | ||
920 | r = radeon_fence_driver_init(rdev); | ||
921 | if (r) | ||
922 | return r; | ||
923 | r = rv770_mc_init(rdev); | ||
924 | if (r) { | ||
925 | if (rdev->flags & RADEON_IS_AGP) { | ||
926 | /* Retry with disabling AGP */ | ||
927 | rv770_fini(rdev); | ||
928 | rdev->flags &= ~RADEON_IS_AGP; | ||
929 | return rv770_init(rdev); | ||
930 | } | ||
931 | return r; | ||
932 | } | ||
933 | /* Memory manager */ | ||
934 | r = radeon_object_init(rdev); | ||
935 | if (r) | ||
936 | return r; | ||
937 | rdev->cp.ring_obj = NULL; | ||
938 | r600_ring_init(rdev, 1024 * 1024); | ||
939 | |||
940 | if (!rdev->me_fw || !rdev->pfp_fw) { | ||
941 | r = r600_cp_init_microcode(rdev); | ||
942 | if (r) { | ||
943 | DRM_ERROR("Failed to load firmware!\n"); | ||
944 | return r; | ||
945 | } | ||
946 | } | ||
947 | |||
948 | r = rv770_resume(rdev); | ||
949 | if (r) { | ||
950 | if (rdev->flags & RADEON_IS_AGP) { | ||
951 | /* Retry with disabling AGP */ | ||
952 | rv770_fini(rdev); | ||
953 | rdev->flags &= ~RADEON_IS_AGP; | ||
954 | return rv770_init(rdev); | ||
955 | } | ||
956 | return r; | ||
957 | } | ||
958 | r = r600_blit_init(rdev); | ||
959 | if (r) { | ||
960 | DRM_ERROR("radeon: failled blitter (%d).\n", r); | ||
961 | return r; | ||
962 | } | ||
963 | r = radeon_ib_pool_init(rdev); | ||
964 | if (r) { | ||
965 | DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); | ||
966 | return r; | ||
967 | } | ||
968 | r = radeon_ib_test(rdev); | ||
969 | if (r) { | ||
970 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | ||
971 | return r; | ||
972 | } | ||
973 | return 0; | ||
974 | } | ||
975 | |||
976 | void rv770_fini(struct radeon_device *rdev) | ||
977 | { | ||
978 | r600_blit_fini(rdev); | ||
979 | radeon_ring_fini(rdev); | ||
980 | rv770_pcie_gart_disable(rdev); | ||
981 | radeon_gart_table_vram_free(rdev); | ||
982 | radeon_gart_fini(rdev); | ||
983 | radeon_gem_fini(rdev); | ||
984 | radeon_fence_driver_fini(rdev); | ||
985 | radeon_clocks_fini(rdev); | ||
986 | #if __OS_HAS_AGP | ||
987 | if (rdev->flags & RADEON_IS_AGP) | ||
988 | radeon_agp_fini(rdev); | ||
989 | #endif | ||
990 | radeon_object_fini(rdev); | ||
991 | if (rdev->is_atom_bios) { | ||
992 | radeon_atombios_fini(rdev); | ||
993 | } else { | ||
994 | radeon_combios_fini(rdev); | ||
995 | } | ||
996 | kfree(rdev->bios); | ||
997 | rdev->bios = NULL; | ||
998 | radeon_dummy_page_fini(rdev); | ||
124 | } | 999 | } |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h new file mode 100644 index 000000000000..4b9c3d6396ff --- /dev/null +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -0,0 +1,341 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2009 Red Hat Inc. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice shall be included in | ||
13 | * all copies or substantial portions of the Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
21 | * OTHER DEALINGS IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: Dave Airlie | ||
24 | * Alex Deucher | ||
25 | * Jerome Glisse | ||
26 | */ | ||
27 | #ifndef RV770_H | ||
28 | #define RV770_H | ||
29 | |||
30 | #define R7XX_MAX_SH_GPRS 256 | ||
31 | #define R7XX_MAX_TEMP_GPRS 16 | ||
32 | #define R7XX_MAX_SH_THREADS 256 | ||
33 | #define R7XX_MAX_SH_STACK_ENTRIES 4096 | ||
34 | #define R7XX_MAX_BACKENDS 8 | ||
35 | #define R7XX_MAX_BACKENDS_MASK 0xff | ||
36 | #define R7XX_MAX_SIMDS 16 | ||
37 | #define R7XX_MAX_SIMDS_MASK 0xffff | ||
38 | #define R7XX_MAX_PIPES 8 | ||
39 | #define R7XX_MAX_PIPES_MASK 0xff | ||
40 | |||
41 | /* Registers */ | ||
42 | #define CB_COLOR0_BASE 0x28040 | ||
43 | #define CB_COLOR1_BASE 0x28044 | ||
44 | #define CB_COLOR2_BASE 0x28048 | ||
45 | #define CB_COLOR3_BASE 0x2804C | ||
46 | #define CB_COLOR4_BASE 0x28050 | ||
47 | #define CB_COLOR5_BASE 0x28054 | ||
48 | #define CB_COLOR6_BASE 0x28058 | ||
49 | #define CB_COLOR7_BASE 0x2805C | ||
50 | #define CB_COLOR7_FRAG 0x280FC | ||
51 | |||
52 | #define CC_GC_SHADER_PIPE_CONFIG 0x8950 | ||
53 | #define CC_RB_BACKEND_DISABLE 0x98F4 | ||
54 | #define BACKEND_DISABLE(x) ((x) << 16) | ||
55 | #define CC_SYS_RB_BACKEND_DISABLE 0x3F88 | ||
56 | |||
57 | #define CGTS_SYS_TCC_DISABLE 0x3F90 | ||
58 | #define CGTS_TCC_DISABLE 0x9148 | ||
59 | #define CGTS_USER_SYS_TCC_DISABLE 0x3F94 | ||
60 | #define CGTS_USER_TCC_DISABLE 0x914C | ||
61 | |||
62 | #define CONFIG_MEMSIZE 0x5428 | ||
63 | |||
64 | #define CP_ME_CNTL 0x86D8 | ||
65 | #define CP_ME_HALT (1<<28) | ||
66 | #define CP_PFP_HALT (1<<26) | ||
67 | #define CP_ME_RAM_DATA 0xC160 | ||
68 | #define CP_ME_RAM_RADDR 0xC158 | ||
69 | #define CP_ME_RAM_WADDR 0xC15C | ||
70 | #define CP_MEQ_THRESHOLDS 0x8764 | ||
71 | #define STQ_SPLIT(x) ((x) << 0) | ||
72 | #define CP_PERFMON_CNTL 0x87FC | ||
73 | #define CP_PFP_UCODE_ADDR 0xC150 | ||
74 | #define CP_PFP_UCODE_DATA 0xC154 | ||
75 | #define CP_QUEUE_THRESHOLDS 0x8760 | ||
76 | #define ROQ_IB1_START(x) ((x) << 0) | ||
77 | #define ROQ_IB2_START(x) ((x) << 8) | ||
78 | #define CP_RB_CNTL 0xC104 | ||
79 | #define RB_BUFSZ(x) ((x)<<0) | ||
80 | #define RB_BLKSZ(x) ((x)<<8) | ||
81 | #define RB_NO_UPDATE (1<<27) | ||
82 | #define RB_RPTR_WR_ENA (1<<31) | ||
83 | #define BUF_SWAP_32BIT (2 << 16) | ||
84 | #define CP_RB_RPTR 0x8700 | ||
85 | #define CP_RB_RPTR_ADDR 0xC10C | ||
86 | #define CP_RB_RPTR_ADDR_HI 0xC110 | ||
87 | #define CP_RB_RPTR_WR 0xC108 | ||
88 | #define CP_RB_WPTR 0xC114 | ||
89 | #define CP_RB_WPTR_ADDR 0xC118 | ||
90 | #define CP_RB_WPTR_ADDR_HI 0xC11C | ||
91 | #define CP_RB_WPTR_DELAY 0x8704 | ||
92 | #define CP_SEM_WAIT_TIMER 0x85BC | ||
93 | |||
94 | #define DB_DEBUG3 0x98B0 | ||
95 | #define DB_CLK_OFF_DELAY(x) ((x) << 11) | ||
96 | #define DB_DEBUG4 0x9B8C | ||
97 | #define DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) | ||
98 | |||
99 | #define DCP_TILING_CONFIG 0x6CA0 | ||
100 | #define PIPE_TILING(x) ((x) << 1) | ||
101 | #define BANK_TILING(x) ((x) << 4) | ||
102 | #define GROUP_SIZE(x) ((x) << 6) | ||
103 | #define ROW_TILING(x) ((x) << 8) | ||
104 | #define BANK_SWAPS(x) ((x) << 11) | ||
105 | #define SAMPLE_SPLIT(x) ((x) << 14) | ||
106 | #define BACKEND_MAP(x) ((x) << 16) | ||
107 | |||
108 | #define GB_TILING_CONFIG 0x98F0 | ||
109 | |||
110 | #define GC_USER_SHADER_PIPE_CONFIG 0x8954 | ||
111 | #define INACTIVE_QD_PIPES(x) ((x) << 8) | ||
112 | #define INACTIVE_QD_PIPES_MASK 0x0000FF00 | ||
113 | #define INACTIVE_SIMDS(x) ((x) << 16) | ||
114 | #define INACTIVE_SIMDS_MASK 0x00FF0000 | ||
115 | |||
116 | #define GRBM_CNTL 0x8000 | ||
117 | #define GRBM_READ_TIMEOUT(x) ((x) << 0) | ||
118 | #define GRBM_SOFT_RESET 0x8020 | ||
119 | #define SOFT_RESET_CP (1<<0) | ||
120 | #define GRBM_STATUS 0x8010 | ||
121 | #define CMDFIFO_AVAIL_MASK 0x0000000F | ||
122 | #define GUI_ACTIVE (1<<31) | ||
123 | #define GRBM_STATUS2 0x8014 | ||
124 | |||
125 | #define HDP_HOST_PATH_CNTL 0x2C00 | ||
126 | #define HDP_NONSURFACE_BASE 0x2C04 | ||
127 | #define HDP_NONSURFACE_INFO 0x2C08 | ||
128 | #define HDP_NONSURFACE_SIZE 0x2C0C | ||
129 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 | ||
130 | #define HDP_TILING_CONFIG 0x2F3C | ||
131 | |||
132 | #define MC_ARB_RAMCFG 0x2760 | ||
133 | #define NOOFBANK_SHIFT 0 | ||
134 | #define NOOFBANK_MASK 0x00000003 | ||
135 | #define NOOFRANK_SHIFT 2 | ||
136 | #define NOOFRANK_MASK 0x00000004 | ||
137 | #define NOOFROWS_SHIFT 3 | ||
138 | #define NOOFROWS_MASK 0x00000038 | ||
139 | #define NOOFCOLS_SHIFT 6 | ||
140 | #define NOOFCOLS_MASK 0x000000C0 | ||
141 | #define CHANSIZE_SHIFT 8 | ||
142 | #define CHANSIZE_MASK 0x00000100 | ||
143 | #define BURSTLENGTH_SHIFT 9 | ||
144 | #define BURSTLENGTH_MASK 0x00000200 | ||
145 | #define MC_VM_AGP_TOP 0x2028 | ||
146 | #define MC_VM_AGP_BOT 0x202C | ||
147 | #define MC_VM_AGP_BASE 0x2030 | ||
148 | #define MC_VM_FB_LOCATION 0x2024 | ||
149 | #define MC_VM_MB_L1_TLB0_CNTL 0x2234 | ||
150 | #define MC_VM_MB_L1_TLB1_CNTL 0x2238 | ||
151 | #define MC_VM_MB_L1_TLB2_CNTL 0x223C | ||
152 | #define MC_VM_MB_L1_TLB3_CNTL 0x2240 | ||
153 | #define ENABLE_L1_TLB (1 << 0) | ||
154 | #define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) | ||
155 | #define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3) | ||
156 | #define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3) | ||
157 | #define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) | ||
158 | #define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3) | ||
159 | #define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) | ||
160 | #define EFFECTIVE_L1_TLB_SIZE(x) ((x)<<15) | ||
161 | #define EFFECTIVE_L1_QUEUE_SIZE(x) ((x)<<18) | ||
162 | #define MC_VM_MD_L1_TLB0_CNTL 0x2654 | ||
163 | #define MC_VM_MD_L1_TLB1_CNTL 0x2658 | ||
164 | #define MC_VM_MD_L1_TLB2_CNTL 0x265C | ||
165 | #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C | ||
166 | #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 | ||
167 | #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 | ||
168 | |||
169 | #define PA_CL_ENHANCE 0x8A14 | ||
170 | #define CLIP_VTX_REORDER_ENA (1 << 0) | ||
171 | #define NUM_CLIP_SEQ(x) ((x) << 1) | ||
172 | #define PA_SC_AA_CONFIG 0x28C04 | ||
173 | #define PA_SC_CLIPRECT_RULE 0x2820C | ||
174 | #define PA_SC_EDGERULE 0x28230 | ||
175 | #define PA_SC_FIFO_SIZE 0x8BCC | ||
176 | #define SC_PRIM_FIFO_SIZE(x) ((x) << 0) | ||
177 | #define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) | ||
178 | #define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24 | ||
179 | #define FORCE_EOV_MAX_CLK_CNT(x) ((x)<<0) | ||
180 | #define FORCE_EOV_MAX_REZ_CNT(x) ((x)<<16) | ||
181 | #define PA_SC_LINE_STIPPLE 0x28A0C | ||
182 | #define PA_SC_LINE_STIPPLE_STATE 0x8B10 | ||
183 | #define PA_SC_MODE_CNTL 0x28A4C | ||
184 | #define PA_SC_MULTI_CHIP_CNTL 0x8B20 | ||
185 | #define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) | ||
186 | |||
187 | #define SCRATCH_REG0 0x8500 | ||
188 | #define SCRATCH_REG1 0x8504 | ||
189 | #define SCRATCH_REG2 0x8508 | ||
190 | #define SCRATCH_REG3 0x850C | ||
191 | #define SCRATCH_REG4 0x8510 | ||
192 | #define SCRATCH_REG5 0x8514 | ||
193 | #define SCRATCH_REG6 0x8518 | ||
194 | #define SCRATCH_REG7 0x851C | ||
195 | #define SCRATCH_UMSK 0x8540 | ||
196 | #define SCRATCH_ADDR 0x8544 | ||
197 | |||
198 | #define SMX_DC_CTL0 0xA020 | ||
199 | #define USE_HASH_FUNCTION (1 << 0) | ||
200 | #define CACHE_DEPTH(x) ((x) << 1) | ||
201 | #define FLUSH_ALL_ON_EVENT (1 << 10) | ||
202 | #define STALL_ON_EVENT (1 << 11) | ||
203 | #define SMX_EVENT_CTL 0xA02C | ||
204 | #define ES_FLUSH_CTL(x) ((x) << 0) | ||
205 | #define GS_FLUSH_CTL(x) ((x) << 3) | ||
206 | #define ACK_FLUSH_CTL(x) ((x) << 6) | ||
207 | #define SYNC_FLUSH_CTL (1 << 8) | ||
208 | |||
209 | #define SPI_CONFIG_CNTL 0x9100 | ||
210 | #define GPR_WRITE_PRIORITY(x) ((x) << 0) | ||
211 | #define DISABLE_INTERP_1 (1 << 5) | ||
212 | #define SPI_CONFIG_CNTL_1 0x913C | ||
213 | #define VTX_DONE_DELAY(x) ((x) << 0) | ||
214 | #define INTERP_ONE_PRIM_PER_ROW (1 << 4) | ||
215 | #define SPI_INPUT_Z 0x286D8 | ||
216 | #define SPI_PS_IN_CONTROL_0 0x286CC | ||
217 | #define NUM_INTERP(x) ((x)<<0) | ||
218 | #define POSITION_ENA (1<<8) | ||
219 | #define POSITION_CENTROID (1<<9) | ||
220 | #define POSITION_ADDR(x) ((x)<<10) | ||
221 | #define PARAM_GEN(x) ((x)<<15) | ||
222 | #define PARAM_GEN_ADDR(x) ((x)<<19) | ||
223 | #define BARYC_SAMPLE_CNTL(x) ((x)<<26) | ||
224 | #define PERSP_GRADIENT_ENA (1<<28) | ||
225 | #define LINEAR_GRADIENT_ENA (1<<29) | ||
226 | #define POSITION_SAMPLE (1<<30) | ||
227 | #define BARYC_AT_SAMPLE_ENA (1<<31) | ||
228 | |||
229 | #define SQ_CONFIG 0x8C00 | ||
230 | #define VC_ENABLE (1 << 0) | ||
231 | #define EXPORT_SRC_C (1 << 1) | ||
232 | #define DX9_CONSTS (1 << 2) | ||
233 | #define ALU_INST_PREFER_VECTOR (1 << 3) | ||
234 | #define DX10_CLAMP (1 << 4) | ||
235 | #define CLAUSE_SEQ_PRIO(x) ((x) << 8) | ||
236 | #define PS_PRIO(x) ((x) << 24) | ||
237 | #define VS_PRIO(x) ((x) << 26) | ||
238 | #define GS_PRIO(x) ((x) << 28) | ||
239 | #define SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8DB0 | ||
240 | #define SIMDA_RING0(x) ((x)<<0) | ||
241 | #define SIMDA_RING1(x) ((x)<<8) | ||
242 | #define SIMDB_RING0(x) ((x)<<16) | ||
243 | #define SIMDB_RING1(x) ((x)<<24) | ||
244 | #define SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8DB4 | ||
245 | #define SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8DB8 | ||
246 | #define SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8DBC | ||
247 | #define SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8DC0 | ||
248 | #define SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8DC4 | ||
249 | #define SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8DC8 | ||
250 | #define SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8DCC | ||
251 | #define ES_PRIO(x) ((x) << 30) | ||
252 | #define SQ_GPR_RESOURCE_MGMT_1 0x8C04 | ||
253 | #define NUM_PS_GPRS(x) ((x) << 0) | ||
254 | #define NUM_VS_GPRS(x) ((x) << 16) | ||
255 | #define DYN_GPR_ENABLE (1 << 27) | ||
256 | #define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) | ||
257 | #define SQ_GPR_RESOURCE_MGMT_2 0x8C08 | ||
258 | #define NUM_GS_GPRS(x) ((x) << 0) | ||
259 | #define NUM_ES_GPRS(x) ((x) << 16) | ||
260 | #define SQ_MS_FIFO_SIZES 0x8CF0 | ||
261 | #define CACHE_FIFO_SIZE(x) ((x) << 0) | ||
262 | #define FETCH_FIFO_HIWATER(x) ((x) << 8) | ||
263 | #define DONE_FIFO_HIWATER(x) ((x) << 16) | ||
264 | #define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) | ||
265 | #define SQ_STACK_RESOURCE_MGMT_1 0x8C10 | ||
266 | #define NUM_PS_STACK_ENTRIES(x) ((x) << 0) | ||
267 | #define NUM_VS_STACK_ENTRIES(x) ((x) << 16) | ||
268 | #define SQ_STACK_RESOURCE_MGMT_2 0x8C14 | ||
269 | #define NUM_GS_STACK_ENTRIES(x) ((x) << 0) | ||
270 | #define NUM_ES_STACK_ENTRIES(x) ((x) << 16) | ||
271 | #define SQ_THREAD_RESOURCE_MGMT 0x8C0C | ||
272 | #define NUM_PS_THREADS(x) ((x) << 0) | ||
273 | #define NUM_VS_THREADS(x) ((x) << 8) | ||
274 | #define NUM_GS_THREADS(x) ((x) << 16) | ||
275 | #define NUM_ES_THREADS(x) ((x) << 24) | ||
276 | |||
277 | #define SX_DEBUG_1 0x9058 | ||
278 | #define ENABLE_NEW_SMX_ADDRESS (1 << 16) | ||
279 | #define SX_EXPORT_BUFFER_SIZES 0x900C | ||
280 | #define COLOR_BUFFER_SIZE(x) ((x) << 0) | ||
281 | #define POSITION_BUFFER_SIZE(x) ((x) << 8) | ||
282 | #define SMX_BUFFER_SIZE(x) ((x) << 16) | ||
283 | #define SX_MISC 0x28350 | ||
284 | |||
285 | #define TA_CNTL_AUX 0x9508 | ||
286 | #define DISABLE_CUBE_WRAP (1 << 0) | ||
287 | #define DISABLE_CUBE_ANISO (1 << 1) | ||
288 | #define SYNC_GRADIENT (1 << 24) | ||
289 | #define SYNC_WALKER (1 << 25) | ||
290 | #define SYNC_ALIGNER (1 << 26) | ||
291 | #define BILINEAR_PRECISION_6_BIT (0 << 31) | ||
292 | #define BILINEAR_PRECISION_8_BIT (1 << 31) | ||
293 | |||
294 | #define TCP_CNTL 0x9610 | ||
295 | |||
296 | #define VGT_CACHE_INVALIDATION 0x88C4 | ||
297 | #define CACHE_INVALIDATION(x) ((x)<<0) | ||
298 | #define VC_ONLY 0 | ||
299 | #define TC_ONLY 1 | ||
300 | #define VC_AND_TC 2 | ||
301 | #define AUTO_INVLD_EN(x) ((x) << 6) | ||
302 | #define NO_AUTO 0 | ||
303 | #define ES_AUTO 1 | ||
304 | #define GS_AUTO 2 | ||
305 | #define ES_AND_GS_AUTO 3 | ||
306 | #define VGT_ES_PER_GS 0x88CC | ||
307 | #define VGT_GS_PER_ES 0x88C8 | ||
308 | #define VGT_GS_PER_VS 0x88E8 | ||
309 | #define VGT_GS_VERTEX_REUSE 0x88D4 | ||
310 | #define VGT_NUM_INSTANCES 0x8974 | ||
311 | #define VGT_OUT_DEALLOC_CNTL 0x28C5C | ||
312 | #define DEALLOC_DIST_MASK 0x0000007F | ||
313 | #define VGT_STRMOUT_EN 0x28AB0 | ||
314 | #define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 | ||
315 | #define VTX_REUSE_DEPTH_MASK 0x000000FF | ||
316 | |||
317 | #define VM_CONTEXT0_CNTL 0x1410 | ||
318 | #define ENABLE_CONTEXT (1 << 0) | ||
319 | #define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) | ||
320 | #define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) | ||
321 | #define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C | ||
322 | #define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C | ||
323 | #define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C | ||
324 | #define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518 | ||
325 | #define VM_L2_CNTL 0x1400 | ||
326 | #define ENABLE_L2_CACHE (1 << 0) | ||
327 | #define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) | ||
328 | #define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) | ||
329 | #define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 14) | ||
330 | #define VM_L2_CNTL2 0x1404 | ||
331 | #define INVALIDATE_ALL_L1_TLBS (1 << 0) | ||
332 | #define INVALIDATE_L2_CACHE (1 << 1) | ||
333 | #define VM_L2_CNTL3 0x1408 | ||
334 | #define BANK_SELECT(x) ((x) << 0) | ||
335 | #define CACHE_UPDATE_MODE(x) ((x) << 6) | ||
336 | #define VM_L2_STATUS 0x140C | ||
337 | #define L2_BUSY (1 << 0) | ||
338 | |||
339 | #define WAIT_UNTIL 0x8040 | ||
340 | |||
341 | #endif | ||