diff options
author | Dave Airlie <airlied@redhat.com> | 2012-12-12 21:03:22 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-12-12 21:03:22 -0500 |
commit | 9add1ac3dd256ad12e266f8403daf928be19953f (patch) | |
tree | cdb9a18960aaf5e1bf851ff752b6e2d10d4fad7a | |
parent | a636a9829175987e74ddd28a2e87ed17ff7adfdc (diff) | |
parent | 86a1881d08f65a42c17071a59c0088dbe2870246 (diff) |
Merge branch 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux into drm-next
* 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux:
drm/radeon: fix fence driver for dma ring when wb is disabled
drm/radeon/si: add VM CS checker support for CP DMA
drm/radeon/cayman: add VM CS checker support for CP DMA
drm/radeon: add support for CP DMA packet to evergreen CS checker
drm/radeon: add support for CP DMA packet to r6xx/r7xx CS checker
drm/radeon: add register headers for CP DMA on r6xx-SI
drm/radeon: improve mc_stop/mc_resume on r5xx-r7xx
drm/radeon: fix amd afusion gpu setup aka sumo v2
drm/radeon: do not move bo to different placement at each cs
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 136 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 72 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_reg.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600d.h | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fence.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv515.c | 122 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 48 |
14 files changed, 516 insertions, 32 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index c66251e4a9b9..8dbc69a6e5bd 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1821,7 +1821,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1821 | case CHIP_SUMO: | 1821 | case CHIP_SUMO: |
1822 | rdev->config.evergreen.num_ses = 1; | 1822 | rdev->config.evergreen.num_ses = 1; |
1823 | rdev->config.evergreen.max_pipes = 4; | 1823 | rdev->config.evergreen.max_pipes = 4; |
1824 | rdev->config.evergreen.max_tile_pipes = 2; | 1824 | rdev->config.evergreen.max_tile_pipes = 4; |
1825 | if (rdev->pdev->device == 0x9648) | 1825 | if (rdev->pdev->device == 0x9648) |
1826 | rdev->config.evergreen.max_simds = 3; | 1826 | rdev->config.evergreen.max_simds = 3; |
1827 | else if ((rdev->pdev->device == 0x9647) || | 1827 | else if ((rdev->pdev->device == 0x9647) || |
@@ -1844,7 +1844,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1844 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | 1844 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; |
1845 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | 1845 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; |
1846 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | 1846 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; |
1847 | gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN; | 1847 | gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN; |
1848 | break; | 1848 | break; |
1849 | case CHIP_SUMO2: | 1849 | case CHIP_SUMO2: |
1850 | rdev->config.evergreen.num_ses = 1; | 1850 | rdev->config.evergreen.num_ses = 1; |
@@ -1866,7 +1866,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1866 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; | 1866 | rdev->config.evergreen.sc_prim_fifo_size = 0x40; |
1867 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; | 1867 | rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; |
1868 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; | 1868 | rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; |
1869 | gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN; | 1869 | gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN; |
1870 | break; | 1870 | break; |
1871 | case CHIP_BARTS: | 1871 | case CHIP_BARTS: |
1872 | rdev->config.evergreen.num_ses = 2; | 1872 | rdev->config.evergreen.num_ses = 2; |
@@ -1914,7 +1914,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1914 | break; | 1914 | break; |
1915 | case CHIP_CAICOS: | 1915 | case CHIP_CAICOS: |
1916 | rdev->config.evergreen.num_ses = 1; | 1916 | rdev->config.evergreen.num_ses = 1; |
1917 | rdev->config.evergreen.max_pipes = 4; | 1917 | rdev->config.evergreen.max_pipes = 2; |
1918 | rdev->config.evergreen.max_tile_pipes = 2; | 1918 | rdev->config.evergreen.max_tile_pipes = 2; |
1919 | rdev->config.evergreen.max_simds = 2; | 1919 | rdev->config.evergreen.max_simds = 2; |
1920 | rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; | 1920 | rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index c042e497e450..62c227104781 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -2232,6 +2232,95 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2232 | ib[idx+2] = upper_32_bits(offset) & 0xff; | 2232 | ib[idx+2] = upper_32_bits(offset) & 0xff; |
2233 | } | 2233 | } |
2234 | break; | 2234 | break; |
2235 | case PACKET3_CP_DMA: | ||
2236 | { | ||
2237 | u32 command, size, info; | ||
2238 | u64 offset, tmp; | ||
2239 | if (pkt->count != 4) { | ||
2240 | DRM_ERROR("bad CP DMA\n"); | ||
2241 | return -EINVAL; | ||
2242 | } | ||
2243 | command = radeon_get_ib_value(p, idx+4); | ||
2244 | size = command & 0x1fffff; | ||
2245 | info = radeon_get_ib_value(p, idx+1); | ||
2246 | if (command & PACKET3_CP_DMA_CMD_SAS) { | ||
2247 | /* src address space is register */ | ||
2248 | /* GDS is ok */ | ||
2249 | if (((info & 0x60000000) >> 29) != 1) { | ||
2250 | DRM_ERROR("CP DMA SAS not supported\n"); | ||
2251 | return -EINVAL; | ||
2252 | } | ||
2253 | } else { | ||
2254 | if (command & PACKET3_CP_DMA_CMD_SAIC) { | ||
2255 | DRM_ERROR("CP DMA SAIC only supported for registers\n"); | ||
2256 | return -EINVAL; | ||
2257 | } | ||
2258 | /* src address space is memory */ | ||
2259 | if (((info & 0x60000000) >> 29) == 0) { | ||
2260 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2261 | if (r) { | ||
2262 | DRM_ERROR("bad CP DMA SRC\n"); | ||
2263 | return -EINVAL; | ||
2264 | } | ||
2265 | |||
2266 | tmp = radeon_get_ib_value(p, idx) + | ||
2267 | ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); | ||
2268 | |||
2269 | offset = reloc->lobj.gpu_offset + tmp; | ||
2270 | |||
2271 | if ((tmp + size) > radeon_bo_size(reloc->robj)) { | ||
2272 | dev_warn(p->dev, "CP DMA src buffer too small (%llu %lu)\n", | ||
2273 | tmp + size, radeon_bo_size(reloc->robj)); | ||
2274 | return -EINVAL; | ||
2275 | } | ||
2276 | |||
2277 | ib[idx] = offset; | ||
2278 | ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff); | ||
2279 | } else if (((info & 0x60000000) >> 29) != 2) { | ||
2280 | DRM_ERROR("bad CP DMA SRC_SEL\n"); | ||
2281 | return -EINVAL; | ||
2282 | } | ||
2283 | } | ||
2284 | if (command & PACKET3_CP_DMA_CMD_DAS) { | ||
2285 | /* dst address space is register */ | ||
2286 | /* GDS is ok */ | ||
2287 | if (((info & 0x00300000) >> 20) != 1) { | ||
2288 | DRM_ERROR("CP DMA DAS not supported\n"); | ||
2289 | return -EINVAL; | ||
2290 | } | ||
2291 | } else { | ||
2292 | /* dst address space is memory */ | ||
2293 | if (command & PACKET3_CP_DMA_CMD_DAIC) { | ||
2294 | DRM_ERROR("CP DMA DAIC only supported for registers\n"); | ||
2295 | return -EINVAL; | ||
2296 | } | ||
2297 | if (((info & 0x00300000) >> 20) == 0) { | ||
2298 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2299 | if (r) { | ||
2300 | DRM_ERROR("bad CP DMA DST\n"); | ||
2301 | return -EINVAL; | ||
2302 | } | ||
2303 | |||
2304 | tmp = radeon_get_ib_value(p, idx+2) + | ||
2305 | ((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32); | ||
2306 | |||
2307 | offset = reloc->lobj.gpu_offset + tmp; | ||
2308 | |||
2309 | if ((tmp + size) > radeon_bo_size(reloc->robj)) { | ||
2310 | dev_warn(p->dev, "CP DMA dst buffer too small (%llu %lu)\n", | ||
2311 | tmp + size, radeon_bo_size(reloc->robj)); | ||
2312 | return -EINVAL; | ||
2313 | } | ||
2314 | |||
2315 | ib[idx+2] = offset; | ||
2316 | ib[idx+3] = upper_32_bits(offset) & 0xff; | ||
2317 | } else { | ||
2318 | DRM_ERROR("bad CP DMA DST_SEL\n"); | ||
2319 | return -EINVAL; | ||
2320 | } | ||
2321 | } | ||
2322 | break; | ||
2323 | } | ||
2235 | case PACKET3_SURFACE_SYNC: | 2324 | case PACKET3_SURFACE_SYNC: |
2236 | if (pkt->count != 3) { | 2325 | if (pkt->count != 3) { |
2237 | DRM_ERROR("bad SURFACE_SYNC\n"); | 2326 | DRM_ERROR("bad SURFACE_SYNC\n"); |
@@ -2843,6 +2932,7 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev, | |||
2843 | u32 idx = pkt->idx + 1; | 2932 | u32 idx = pkt->idx + 1; |
2844 | u32 idx_value = ib[idx]; | 2933 | u32 idx_value = ib[idx]; |
2845 | u32 start_reg, end_reg, reg, i; | 2934 | u32 start_reg, end_reg, reg, i; |
2935 | u32 command, info; | ||
2846 | 2936 | ||
2847 | switch (pkt->opcode) { | 2937 | switch (pkt->opcode) { |
2848 | case PACKET3_NOP: | 2938 | case PACKET3_NOP: |
@@ -2917,6 +3007,52 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev, | |||
2917 | return -EINVAL; | 3007 | return -EINVAL; |
2918 | } | 3008 | } |
2919 | break; | 3009 | break; |
3010 | case PACKET3_CP_DMA: | ||
3011 | command = ib[idx + 4]; | ||
3012 | info = ib[idx + 1]; | ||
3013 | if (command & PACKET3_CP_DMA_CMD_SAS) { | ||
3014 | /* src address space is register */ | ||
3015 | if (((info & 0x60000000) >> 29) == 0) { | ||
3016 | start_reg = idx_value << 2; | ||
3017 | if (command & PACKET3_CP_DMA_CMD_SAIC) { | ||
3018 | reg = start_reg; | ||
3019 | if (!evergreen_vm_reg_valid(reg)) { | ||
3020 | DRM_ERROR("CP DMA Bad SRC register\n"); | ||
3021 | return -EINVAL; | ||
3022 | } | ||
3023 | } else { | ||
3024 | for (i = 0; i < (command & 0x1fffff); i++) { | ||
3025 | reg = start_reg + (4 * i); | ||
3026 | if (!evergreen_vm_reg_valid(reg)) { | ||
3027 | DRM_ERROR("CP DMA Bad SRC register\n"); | ||
3028 | return -EINVAL; | ||
3029 | } | ||
3030 | } | ||
3031 | } | ||
3032 | } | ||
3033 | } | ||
3034 | if (command & PACKET3_CP_DMA_CMD_DAS) { | ||
3035 | /* dst address space is register */ | ||
3036 | if (((info & 0x00300000) >> 20) == 0) { | ||
3037 | start_reg = ib[idx + 2]; | ||
3038 | if (command & PACKET3_CP_DMA_CMD_DAIC) { | ||
3039 | reg = start_reg; | ||
3040 | if (!evergreen_vm_reg_valid(reg)) { | ||
3041 | DRM_ERROR("CP DMA Bad DST register\n"); | ||
3042 | return -EINVAL; | ||
3043 | } | ||
3044 | } else { | ||
3045 | for (i = 0; i < (command & 0x1fffff); i++) { | ||
3046 | reg = start_reg + (4 * i); | ||
3047 | if (!evergreen_vm_reg_valid(reg)) { | ||
3048 | DRM_ERROR("CP DMA Bad DST register\n"); | ||
3049 | return -EINVAL; | ||
3050 | } | ||
3051 | } | ||
3052 | } | ||
3053 | } | ||
3054 | } | ||
3055 | break; | ||
2920 | default: | 3056 | default: |
2921 | return -EINVAL; | 3057 | return -EINVAL; |
2922 | } | 3058 | } |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 7b4a650e33b2..cb9baaac9e85 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -45,6 +45,8 @@ | |||
45 | #define TURKS_GB_ADDR_CONFIG_GOLDEN 0x02010002 | 45 | #define TURKS_GB_ADDR_CONFIG_GOLDEN 0x02010002 |
46 | #define CEDAR_GB_ADDR_CONFIG_GOLDEN 0x02010001 | 46 | #define CEDAR_GB_ADDR_CONFIG_GOLDEN 0x02010001 |
47 | #define CAICOS_GB_ADDR_CONFIG_GOLDEN 0x02010001 | 47 | #define CAICOS_GB_ADDR_CONFIG_GOLDEN 0x02010001 |
48 | #define SUMO_GB_ADDR_CONFIG_GOLDEN 0x02010002 | ||
49 | #define SUMO2_GB_ADDR_CONFIG_GOLDEN 0x02010002 | ||
48 | 50 | ||
49 | /* Registers */ | 51 | /* Registers */ |
50 | 52 | ||
@@ -1033,6 +1035,53 @@ | |||
1033 | #define PACKET3_WAIT_REG_MEM 0x3C | 1035 | #define PACKET3_WAIT_REG_MEM 0x3C |
1034 | #define PACKET3_MEM_WRITE 0x3D | 1036 | #define PACKET3_MEM_WRITE 0x3D |
1035 | #define PACKET3_INDIRECT_BUFFER 0x32 | 1037 | #define PACKET3_INDIRECT_BUFFER 0x32 |
1038 | #define PACKET3_CP_DMA 0x41 | ||
1039 | /* 1. header | ||
1040 | * 2. SRC_ADDR_LO or DATA [31:0] | ||
1041 | * 3. CP_SYNC [31] | SRC_SEL [30:29] | ENGINE [27] | DST_SEL [21:20] | | ||
1042 | * SRC_ADDR_HI [7:0] | ||
1043 | * 4. DST_ADDR_LO [31:0] | ||
1044 | * 5. DST_ADDR_HI [7:0] | ||
1045 | * 6. COMMAND [29:22] | BYTE_COUNT [20:0] | ||
1046 | */ | ||
1047 | # define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20) | ||
1048 | /* 0 - SRC_ADDR | ||
1049 | * 1 - GDS | ||
1050 | */ | ||
1051 | # define PACKET3_CP_DMA_ENGINE(x) ((x) << 27) | ||
1052 | /* 0 - ME | ||
1053 | * 1 - PFP | ||
1054 | */ | ||
1055 | # define PACKET3_CP_DMA_SRC_SEL(x) ((x) << 29) | ||
1056 | /* 0 - SRC_ADDR | ||
1057 | * 1 - GDS | ||
1058 | * 2 - DATA | ||
1059 | */ | ||
1060 | # define PACKET3_CP_DMA_CP_SYNC (1 << 31) | ||
1061 | /* COMMAND */ | ||
1062 | # define PACKET3_CP_DMA_DIS_WC (1 << 21) | ||
1063 | # define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) | ||
1064 | /* 0 - none | ||
1065 | * 1 - 8 in 16 | ||
1066 | * 2 - 8 in 32 | ||
1067 | * 3 - 8 in 64 | ||
1068 | */ | ||
1069 | # define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24) | ||
1070 | /* 0 - none | ||
1071 | * 1 - 8 in 16 | ||
1072 | * 2 - 8 in 32 | ||
1073 | * 3 - 8 in 64 | ||
1074 | */ | ||
1075 | # define PACKET3_CP_DMA_CMD_SAS (1 << 26) | ||
1076 | /* 0 - memory | ||
1077 | * 1 - register | ||
1078 | */ | ||
1079 | # define PACKET3_CP_DMA_CMD_DAS (1 << 27) | ||
1080 | /* 0 - memory | ||
1081 | * 1 - register | ||
1082 | */ | ||
1083 | # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) | ||
1084 | # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) | ||
1036 | #define PACKET3_SURFACE_SYNC 0x43 | 1085 | #define PACKET3_SURFACE_SYNC 0x43 |
1037 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | 1086 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
1038 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) | 1087 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a76eca18f134..2aaf147969bd 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2533,11 +2533,12 @@ void r600_dma_fence_ring_emit(struct radeon_device *rdev, | |||
2533 | { | 2533 | { |
2534 | struct radeon_ring *ring = &rdev->ring[fence->ring]; | 2534 | struct radeon_ring *ring = &rdev->ring[fence->ring]; |
2535 | u64 addr = rdev->fence_drv[fence->ring].gpu_addr; | 2535 | u64 addr = rdev->fence_drv[fence->ring].gpu_addr; |
2536 | |||
2536 | /* write the fence */ | 2537 | /* write the fence */ |
2537 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0)); | 2538 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0)); |
2538 | radeon_ring_write(ring, addr & 0xfffffffc); | 2539 | radeon_ring_write(ring, addr & 0xfffffffc); |
2539 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff)); | 2540 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff)); |
2540 | radeon_ring_write(ring, fence->seq); | 2541 | radeon_ring_write(ring, lower_32_bits(fence->seq)); |
2541 | /* generate an interrupt */ | 2542 | /* generate an interrupt */ |
2542 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); | 2543 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); |
2543 | } | 2544 | } |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 211c40252fe0..5d6e7f959e75 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -1949,6 +1949,78 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
1949 | ib[idx+2] = upper_32_bits(offset) & 0xff; | 1949 | ib[idx+2] = upper_32_bits(offset) & 0xff; |
1950 | } | 1950 | } |
1951 | break; | 1951 | break; |
1952 | case PACKET3_CP_DMA: | ||
1953 | { | ||
1954 | u32 command, size; | ||
1955 | u64 offset, tmp; | ||
1956 | if (pkt->count != 4) { | ||
1957 | DRM_ERROR("bad CP DMA\n"); | ||
1958 | return -EINVAL; | ||
1959 | } | ||
1960 | command = radeon_get_ib_value(p, idx+4); | ||
1961 | size = command & 0x1fffff; | ||
1962 | if (command & PACKET3_CP_DMA_CMD_SAS) { | ||
1963 | /* src address space is register */ | ||
1964 | DRM_ERROR("CP DMA SAS not supported\n"); | ||
1965 | return -EINVAL; | ||
1966 | } else { | ||
1967 | if (command & PACKET3_CP_DMA_CMD_SAIC) { | ||
1968 | DRM_ERROR("CP DMA SAIC only supported for registers\n"); | ||
1969 | return -EINVAL; | ||
1970 | } | ||
1971 | /* src address space is memory */ | ||
1972 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1973 | if (r) { | ||
1974 | DRM_ERROR("bad CP DMA SRC\n"); | ||
1975 | return -EINVAL; | ||
1976 | } | ||
1977 | |||
1978 | tmp = radeon_get_ib_value(p, idx) + | ||
1979 | ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); | ||
1980 | |||
1981 | offset = reloc->lobj.gpu_offset + tmp; | ||
1982 | |||
1983 | if ((tmp + size) > radeon_bo_size(reloc->robj)) { | ||
1984 | dev_warn(p->dev, "CP DMA src buffer too small (%llu %lu)\n", | ||
1985 | tmp + size, radeon_bo_size(reloc->robj)); | ||
1986 | return -EINVAL; | ||
1987 | } | ||
1988 | |||
1989 | ib[idx] = offset; | ||
1990 | ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff); | ||
1991 | } | ||
1992 | if (command & PACKET3_CP_DMA_CMD_DAS) { | ||
1993 | /* dst address space is register */ | ||
1994 | DRM_ERROR("CP DMA DAS not supported\n"); | ||
1995 | return -EINVAL; | ||
1996 | } else { | ||
1997 | /* dst address space is memory */ | ||
1998 | if (command & PACKET3_CP_DMA_CMD_DAIC) { | ||
1999 | DRM_ERROR("CP DMA DAIC only supported for registers\n"); | ||
2000 | return -EINVAL; | ||
2001 | } | ||
2002 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
2003 | if (r) { | ||
2004 | DRM_ERROR("bad CP DMA DST\n"); | ||
2005 | return -EINVAL; | ||
2006 | } | ||
2007 | |||
2008 | tmp = radeon_get_ib_value(p, idx+2) + | ||
2009 | ((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32); | ||
2010 | |||
2011 | offset = reloc->lobj.gpu_offset + tmp; | ||
2012 | |||
2013 | if ((tmp + size) > radeon_bo_size(reloc->robj)) { | ||
2014 | dev_warn(p->dev, "CP DMA dst buffer too small (%llu %lu)\n", | ||
2015 | tmp + size, radeon_bo_size(reloc->robj)); | ||
2016 | return -EINVAL; | ||
2017 | } | ||
2018 | |||
2019 | ib[idx+2] = offset; | ||
2020 | ib[idx+3] = upper_32_bits(offset) & 0xff; | ||
2021 | } | ||
2022 | break; | ||
2023 | } | ||
1952 | case PACKET3_SURFACE_SYNC: | 2024 | case PACKET3_SURFACE_SYNC: |
1953 | if (pkt->count != 3) { | 2025 | if (pkt->count != 3) { |
1954 | DRM_ERROR("bad SURFACE_SYNC\n"); | 2026 | DRM_ERROR("bad SURFACE_SYNC\n"); |
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h index 2b960cb5c18a..909219b1bf80 100644 --- a/drivers/gpu/drm/radeon/r600_reg.h +++ b/drivers/gpu/drm/radeon/r600_reg.h | |||
@@ -96,6 +96,15 @@ | |||
96 | #define R600_CONFIG_F0_BASE 0x542C | 96 | #define R600_CONFIG_F0_BASE 0x542C |
97 | #define R600_CONFIG_APER_SIZE 0x5430 | 97 | #define R600_CONFIG_APER_SIZE 0x5430 |
98 | 98 | ||
99 | #define R600_BIF_FB_EN 0x5490 | ||
100 | #define R600_FB_READ_EN (1 << 0) | ||
101 | #define R600_FB_WRITE_EN (1 << 1) | ||
102 | |||
103 | #define R600_CITF_CNTL 0x200c | ||
104 | #define R600_BLACKOUT_MASK 0x00000003 | ||
105 | |||
106 | #define R700_MC_CITF_CNTL 0x25c0 | ||
107 | |||
99 | #define R600_ROM_CNTL 0x1600 | 108 | #define R600_ROM_CNTL 0x1600 |
100 | # define R600_SCK_OVERWRITE (1 << 1) | 109 | # define R600_SCK_OVERWRITE (1 << 1) |
101 | # define R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT 28 | 110 | # define R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT 28 |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index a596c554a3a0..4a53402b1852 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -1186,6 +1186,38 @@ | |||
1186 | #define PACKET3_WAIT_REG_MEM 0x3C | 1186 | #define PACKET3_WAIT_REG_MEM 0x3C |
1187 | #define PACKET3_MEM_WRITE 0x3D | 1187 | #define PACKET3_MEM_WRITE 0x3D |
1188 | #define PACKET3_INDIRECT_BUFFER 0x32 | 1188 | #define PACKET3_INDIRECT_BUFFER 0x32 |
1189 | #define PACKET3_CP_DMA 0x41 | ||
1190 | /* 1. header | ||
1191 | * 2. SRC_ADDR_LO [31:0] | ||
1192 | * 3. CP_SYNC [31] | SRC_ADDR_HI [7:0] | ||
1193 | * 4. DST_ADDR_LO [31:0] | ||
1194 | * 5. DST_ADDR_HI [7:0] | ||
1195 | * 6. COMMAND [29:22] | BYTE_COUNT [20:0] | ||
1196 | */ | ||
1197 | # define PACKET3_CP_DMA_CP_SYNC (1 << 31) | ||
1198 | /* COMMAND */ | ||
1199 | # define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) | ||
1200 | /* 0 - none | ||
1201 | * 1 - 8 in 16 | ||
1202 | * 2 - 8 in 32 | ||
1203 | * 3 - 8 in 64 | ||
1204 | */ | ||
1205 | # define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24) | ||
1206 | /* 0 - none | ||
1207 | * 1 - 8 in 16 | ||
1208 | * 2 - 8 in 32 | ||
1209 | * 3 - 8 in 64 | ||
1210 | */ | ||
1211 | # define PACKET3_CP_DMA_CMD_SAS (1 << 26) | ||
1212 | /* 0 - memory | ||
1213 | * 1 - register | ||
1214 | */ | ||
1215 | # define PACKET3_CP_DMA_CMD_DAS (1 << 27) | ||
1216 | /* 0 - memory | ||
1217 | * 1 - register | ||
1218 | */ | ||
1219 | # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) | ||
1220 | # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) | ||
1189 | #define PACKET3_SURFACE_SYNC 0x43 | 1221 | #define PACKET3_SURFACE_SYNC 0x43 |
1190 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) | 1222 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
1191 | # define PACKET3_TC_ACTION_ENA (1 << 23) | 1223 | # define PACKET3_TC_ACTION_ENA (1 << 23) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5d68346b2c01..1b9120a875ef 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -318,6 +318,7 @@ struct radeon_bo { | |||
318 | struct list_head list; | 318 | struct list_head list; |
319 | /* Protected by tbo.reserved */ | 319 | /* Protected by tbo.reserved */ |
320 | u32 placements[3]; | 320 | u32 placements[3]; |
321 | u32 busy_placements[3]; | ||
321 | struct ttm_placement placement; | 322 | struct ttm_placement placement; |
322 | struct ttm_buffer_object tbo; | 323 | struct ttm_buffer_object tbo; |
323 | struct ttm_bo_kmap_obj kmap; | 324 | struct ttm_bo_kmap_obj kmap; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index ae56673d2410..c338931190a5 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -263,6 +263,7 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); | |||
263 | struct rv515_mc_save { | 263 | struct rv515_mc_save { |
264 | u32 vga_render_control; | 264 | u32 vga_render_control; |
265 | u32 vga_hdp_control; | 265 | u32 vga_hdp_control; |
266 | bool crtc_enabled[2]; | ||
266 | }; | 267 | }; |
267 | 268 | ||
268 | int rv515_init(struct radeon_device *rdev); | 269 | int rv515_init(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 22bd6c2c2740..410a975a8eec 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -772,7 +772,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) | |||
772 | int r; | 772 | int r; |
773 | 773 | ||
774 | radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); | 774 | radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); |
775 | if (rdev->wb.use_event) { | 775 | if (rdev->wb.use_event || !radeon_ring_supports_scratch_reg(rdev, &rdev->ring[ring])) { |
776 | rdev->fence_drv[ring].scratch_reg = 0; | 776 | rdev->fence_drv[ring].scratch_reg = 0; |
777 | index = R600_WB_EVENT_OFFSET + ring * 4; | 777 | index = R600_WB_EVENT_OFFSET + ring * 4; |
778 | } else { | 778 | } else { |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index bfb332e616dc..93d3445477be 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -84,7 +84,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
84 | rbo->placement.fpfn = 0; | 84 | rbo->placement.fpfn = 0; |
85 | rbo->placement.lpfn = 0; | 85 | rbo->placement.lpfn = 0; |
86 | rbo->placement.placement = rbo->placements; | 86 | rbo->placement.placement = rbo->placements; |
87 | rbo->placement.busy_placement = rbo->placements; | ||
88 | if (domain & RADEON_GEM_DOMAIN_VRAM) | 87 | if (domain & RADEON_GEM_DOMAIN_VRAM) |
89 | rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | | 88 | rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | |
90 | TTM_PL_FLAG_VRAM; | 89 | TTM_PL_FLAG_VRAM; |
@@ -105,6 +104,14 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
105 | if (!c) | 104 | if (!c) |
106 | rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; | 105 | rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; |
107 | rbo->placement.num_placement = c; | 106 | rbo->placement.num_placement = c; |
107 | |||
108 | c = 0; | ||
109 | rbo->placement.busy_placement = rbo->busy_placements; | ||
110 | if (rbo->rdev->flags & RADEON_IS_AGP) { | ||
111 | rbo->busy_placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT; | ||
112 | } else { | ||
113 | rbo->busy_placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT; | ||
114 | } | ||
108 | rbo->placement.num_busy_placement = c; | 115 | rbo->placement.num_busy_placement = c; |
109 | } | 116 | } |
110 | 117 | ||
@@ -350,7 +357,6 @@ int radeon_bo_list_validate(struct list_head *head) | |||
350 | { | 357 | { |
351 | struct radeon_bo_list *lobj; | 358 | struct radeon_bo_list *lobj; |
352 | struct radeon_bo *bo; | 359 | struct radeon_bo *bo; |
353 | u32 domain; | ||
354 | int r; | 360 | int r; |
355 | 361 | ||
356 | r = ttm_eu_reserve_buffers(head); | 362 | r = ttm_eu_reserve_buffers(head); |
@@ -360,17 +366,9 @@ int radeon_bo_list_validate(struct list_head *head) | |||
360 | list_for_each_entry(lobj, head, tv.head) { | 366 | list_for_each_entry(lobj, head, tv.head) { |
361 | bo = lobj->bo; | 367 | bo = lobj->bo; |
362 | if (!bo->pin_count) { | 368 | if (!bo->pin_count) { |
363 | domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; | ||
364 | |||
365 | retry: | ||
366 | radeon_ttm_placement_from_domain(bo, domain); | ||
367 | r = ttm_bo_validate(&bo->tbo, &bo->placement, | 369 | r = ttm_bo_validate(&bo->tbo, &bo->placement, |
368 | true, false); | 370 | true, false); |
369 | if (unlikely(r)) { | 371 | if (unlikely(r)) { |
370 | if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) { | ||
371 | domain |= RADEON_GEM_DOMAIN_GTT; | ||
372 | goto retry; | ||
373 | } | ||
374 | return r; | 372 | return r; |
375 | } | 373 | } |
376 | } | 374 | } |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 785d09590b24..2bb6d0e84b3d 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -40,6 +40,12 @@ static int rv515_debugfs_ga_info_init(struct radeon_device *rdev); | |||
40 | static void rv515_gpu_init(struct radeon_device *rdev); | 40 | static void rv515_gpu_init(struct radeon_device *rdev); |
41 | int rv515_mc_wait_for_idle(struct radeon_device *rdev); | 41 | int rv515_mc_wait_for_idle(struct radeon_device *rdev); |
42 | 42 | ||
43 | static const u32 crtc_offsets[2] = | ||
44 | { | ||
45 | 0, | ||
46 | AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL | ||
47 | }; | ||
48 | |||
43 | void rv515_debugfs(struct radeon_device *rdev) | 49 | void rv515_debugfs(struct radeon_device *rdev) |
44 | { | 50 | { |
45 | if (r100_debugfs_rbbm_init(rdev)) { | 51 | if (r100_debugfs_rbbm_init(rdev)) { |
@@ -281,30 +287,114 @@ static int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
281 | 287 | ||
282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | 288 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) |
283 | { | 289 | { |
290 | u32 crtc_enabled, tmp, frame_count, blackout; | ||
291 | int i, j; | ||
292 | |||
284 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); | 293 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); |
285 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); | 294 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); |
286 | 295 | ||
287 | /* Stop all video */ | 296 | /* disable VGA render */ |
288 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
289 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); | 297 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); |
290 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | 298 | /* blank the display controllers */ |
291 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | 299 | for (i = 0; i < rdev->num_crtc; i++) { |
292 | WREG32(R_006080_D1CRTC_CONTROL, 0); | 300 | crtc_enabled = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]) & AVIVO_CRTC_EN; |
293 | WREG32(R_006880_D2CRTC_CONTROL, 0); | 301 | if (crtc_enabled) { |
294 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | 302 | save->crtc_enabled[i] = true; |
295 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 303 | tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); |
296 | WREG32(R_000330_D1VGA_CONTROL, 0); | 304 | if (!(tmp & AVIVO_CRTC_DISP_READ_REQUEST_DISABLE)) { |
297 | WREG32(R_000338_D2VGA_CONTROL, 0); | 305 | radeon_wait_for_vblank(rdev, i); |
306 | tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; | ||
307 | WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); | ||
308 | } | ||
309 | /* wait for the next frame */ | ||
310 | frame_count = radeon_get_vblank_counter(rdev, i); | ||
311 | for (j = 0; j < rdev->usec_timeout; j++) { | ||
312 | if (radeon_get_vblank_counter(rdev, i) != frame_count) | ||
313 | break; | ||
314 | udelay(1); | ||
315 | } | ||
316 | } else { | ||
317 | save->crtc_enabled[i] = false; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | radeon_mc_wait_for_idle(rdev); | ||
322 | |||
323 | if (rdev->family >= CHIP_R600) { | ||
324 | if (rdev->family >= CHIP_RV770) | ||
325 | blackout = RREG32(R700_MC_CITF_CNTL); | ||
326 | else | ||
327 | blackout = RREG32(R600_CITF_CNTL); | ||
328 | if ((blackout & R600_BLACKOUT_MASK) != R600_BLACKOUT_MASK) { | ||
329 | /* Block CPU access */ | ||
330 | WREG32(R600_BIF_FB_EN, 0); | ||
331 | /* blackout the MC */ | ||
332 | blackout |= R600_BLACKOUT_MASK; | ||
333 | if (rdev->family >= CHIP_RV770) | ||
334 | WREG32(R700_MC_CITF_CNTL, blackout); | ||
335 | else | ||
336 | WREG32(R600_CITF_CNTL, blackout); | ||
337 | } | ||
338 | } | ||
298 | } | 339 | } |
299 | 340 | ||
300 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | 341 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) |
301 | { | 342 | { |
302 | WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start); | 343 | u32 tmp, frame_count; |
303 | WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start); | 344 | int i, j; |
304 | WREG32(R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start); | 345 | |
305 | WREG32(R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start); | 346 | /* update crtc base addresses */ |
306 | WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); | 347 | for (i = 0; i < rdev->num_crtc; i++) { |
307 | /* Unlock host access */ | 348 | if (rdev->family >= CHIP_RV770) { |
349 | if (i == 1) { | ||
350 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, | ||
351 | upper_32_bits(rdev->mc.vram_start)); | ||
352 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, | ||
353 | upper_32_bits(rdev->mc.vram_start)); | ||
354 | } else { | ||
355 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, | ||
356 | upper_32_bits(rdev->mc.vram_start)); | ||
357 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, | ||
358 | upper_32_bits(rdev->mc.vram_start)); | ||
359 | } | ||
360 | } | ||
361 | WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], | ||
362 | (u32)rdev->mc.vram_start); | ||
363 | WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], | ||
364 | (u32)rdev->mc.vram_start); | ||
365 | } | ||
366 | WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); | ||
367 | |||
368 | if (rdev->family >= CHIP_R600) { | ||
369 | /* unblackout the MC */ | ||
370 | if (rdev->family >= CHIP_RV770) | ||
371 | tmp = RREG32(R700_MC_CITF_CNTL); | ||
372 | else | ||
373 | tmp = RREG32(R600_CITF_CNTL); | ||
374 | tmp &= ~R600_BLACKOUT_MASK; | ||
375 | if (rdev->family >= CHIP_RV770) | ||
376 | WREG32(R700_MC_CITF_CNTL, tmp); | ||
377 | else | ||
378 | WREG32(R600_CITF_CNTL, tmp); | ||
379 | /* allow CPU access */ | ||
380 | WREG32(R600_BIF_FB_EN, R600_FB_READ_EN | R600_FB_WRITE_EN); | ||
381 | } | ||
382 | |||
383 | for (i = 0; i < rdev->num_crtc; i++) { | ||
384 | if (save->crtc_enabled[i]) { | ||
385 | tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); | ||
386 | tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; | ||
387 | WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); | ||
388 | /* wait for the next frame */ | ||
389 | frame_count = radeon_get_vblank_counter(rdev, i); | ||
390 | for (j = 0; j < rdev->usec_timeout; j++) { | ||
391 | if (radeon_get_vblank_counter(rdev, i) != frame_count) | ||
392 | break; | ||
393 | udelay(1); | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | /* Unlock vga access */ | ||
308 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 398 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
309 | mdelay(1); | 399 | mdelay(1); |
310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 400 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index f6e7815e1860..7e835d94df4a 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -2550,6 +2550,7 @@ static int si_vm_packet3_gfx_check(struct radeon_device *rdev, | |||
2550 | u32 idx = pkt->idx + 1; | 2550 | u32 idx = pkt->idx + 1; |
2551 | u32 idx_value = ib[idx]; | 2551 | u32 idx_value = ib[idx]; |
2552 | u32 start_reg, end_reg, reg, i; | 2552 | u32 start_reg, end_reg, reg, i; |
2553 | u32 command, info; | ||
2553 | 2554 | ||
2554 | switch (pkt->opcode) { | 2555 | switch (pkt->opcode) { |
2555 | case PACKET3_NOP: | 2556 | case PACKET3_NOP: |
@@ -2649,6 +2650,52 @@ static int si_vm_packet3_gfx_check(struct radeon_device *rdev, | |||
2649 | return -EINVAL; | 2650 | return -EINVAL; |
2650 | } | 2651 | } |
2651 | break; | 2652 | break; |
2653 | case PACKET3_CP_DMA: | ||
2654 | command = ib[idx + 4]; | ||
2655 | info = ib[idx + 1]; | ||
2656 | if (command & PACKET3_CP_DMA_CMD_SAS) { | ||
2657 | /* src address space is register */ | ||
2658 | if (((info & 0x60000000) >> 29) == 0) { | ||
2659 | start_reg = idx_value << 2; | ||
2660 | if (command & PACKET3_CP_DMA_CMD_SAIC) { | ||
2661 | reg = start_reg; | ||
2662 | if (!si_vm_reg_valid(reg)) { | ||
2663 | DRM_ERROR("CP DMA Bad SRC register\n"); | ||
2664 | return -EINVAL; | ||
2665 | } | ||
2666 | } else { | ||
2667 | for (i = 0; i < (command & 0x1fffff); i++) { | ||
2668 | reg = start_reg + (4 * i); | ||
2669 | if (!si_vm_reg_valid(reg)) { | ||
2670 | DRM_ERROR("CP DMA Bad SRC register\n"); | ||
2671 | return -EINVAL; | ||
2672 | } | ||
2673 | } | ||
2674 | } | ||
2675 | } | ||
2676 | } | ||
2677 | if (command & PACKET3_CP_DMA_CMD_DAS) { | ||
2678 | /* dst address space is register */ | ||
2679 | if (((info & 0x00300000) >> 20) == 0) { | ||
2680 | start_reg = ib[idx + 2]; | ||
2681 | if (command & PACKET3_CP_DMA_CMD_DAIC) { | ||
2682 | reg = start_reg; | ||
2683 | if (!si_vm_reg_valid(reg)) { | ||
2684 | DRM_ERROR("CP DMA Bad DST register\n"); | ||
2685 | return -EINVAL; | ||
2686 | } | ||
2687 | } else { | ||
2688 | for (i = 0; i < (command & 0x1fffff); i++) { | ||
2689 | reg = start_reg + (4 * i); | ||
2690 | if (!si_vm_reg_valid(reg)) { | ||
2691 | DRM_ERROR("CP DMA Bad DST register\n"); | ||
2692 | return -EINVAL; | ||
2693 | } | ||
2694 | } | ||
2695 | } | ||
2696 | } | ||
2697 | } | ||
2698 | break; | ||
2652 | default: | 2699 | default: |
2653 | DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode); | 2700 | DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode); |
2654 | return -EINVAL; | 2701 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index e153c254fbfb..62b46215d423 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -849,6 +849,54 @@ | |||
849 | #define PACKET3_WAIT_REG_MEM 0x3C | 849 | #define PACKET3_WAIT_REG_MEM 0x3C |
850 | #define PACKET3_MEM_WRITE 0x3D | 850 | #define PACKET3_MEM_WRITE 0x3D |
851 | #define PACKET3_COPY_DATA 0x40 | 851 | #define PACKET3_COPY_DATA 0x40 |
852 | #define PACKET3_CP_DMA 0x41 | ||
853 | /* 1. header | ||
854 | * 2. SRC_ADDR_LO or DATA [31:0] | ||
855 | * 3. CP_SYNC [31] | SRC_SEL [30:29] | ENGINE [27] | DST_SEL [21:20] | | ||
856 | * SRC_ADDR_HI [7:0] | ||
857 | * 4. DST_ADDR_LO [31:0] | ||
858 | * 5. DST_ADDR_HI [7:0] | ||
859 | * 6. COMMAND [30:21] | BYTE_COUNT [20:0] | ||
860 | */ | ||
861 | # define PACKET3_CP_DMA_DST_SEL(x) ((x) << 20) | ||
862 | /* 0 - SRC_ADDR | ||
863 | * 1 - GDS | ||
864 | */ | ||
865 | # define PACKET3_CP_DMA_ENGINE(x) ((x) << 27) | ||
866 | /* 0 - ME | ||
867 | * 1 - PFP | ||
868 | */ | ||
869 | # define PACKET3_CP_DMA_SRC_SEL(x) ((x) << 29) | ||
870 | /* 0 - SRC_ADDR | ||
871 | * 1 - GDS | ||
872 | * 2 - DATA | ||
873 | */ | ||
874 | # define PACKET3_CP_DMA_CP_SYNC (1 << 31) | ||
875 | /* COMMAND */ | ||
876 | # define PACKET3_CP_DMA_DIS_WC (1 << 21) | ||
877 | # define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23) | ||
878 | /* 0 - none | ||
879 | * 1 - 8 in 16 | ||
880 | * 2 - 8 in 32 | ||
881 | * 3 - 8 in 64 | ||
882 | */ | ||
883 | # define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24) | ||
884 | /* 0 - none | ||
885 | * 1 - 8 in 16 | ||
886 | * 2 - 8 in 32 | ||
887 | * 3 - 8 in 64 | ||
888 | */ | ||
889 | # define PACKET3_CP_DMA_CMD_SAS (1 << 26) | ||
890 | /* 0 - memory | ||
891 | * 1 - register | ||
892 | */ | ||
893 | # define PACKET3_CP_DMA_CMD_DAS (1 << 27) | ||
894 | /* 0 - memory | ||
895 | * 1 - register | ||
896 | */ | ||
897 | # define PACKET3_CP_DMA_CMD_SAIC (1 << 28) | ||
898 | # define PACKET3_CP_DMA_CMD_DAIC (1 << 29) | ||
899 | # define PACKET3_CP_DMA_CMD_RAW_WAIT (1 << 30) | ||
852 | #define PACKET3_PFP_SYNC_ME 0x42 | 900 | #define PACKET3_PFP_SYNC_ME 0x42 |
853 | #define PACKET3_SURFACE_SYNC 0x43 | 901 | #define PACKET3_SURFACE_SYNC 0x43 |
854 | # define PACKET3_DEST_BASE_0_ENA (1 << 0) | 902 | # define PACKET3_DEST_BASE_0_ENA (1 << 0) |