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) |
