diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 603 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 285 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 19 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_combios.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_cp.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_cs.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_cursor.c | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.c | 4 | ||||
| -rw-r--r-- | include/uapi/drm/radeon_drm.h | 1 |
16 files changed, 897 insertions, 127 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 62c227104781..74c6b42d2597 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #define MAX(a,b) (((a)>(b))?(a):(b)) | 34 | #define MAX(a,b) (((a)>(b))?(a):(b)) |
| 35 | #define MIN(a,b) (((a)<(b))?(a):(b)) | 35 | #define MIN(a,b) (((a)<(b))?(a):(b)) |
| 36 | 36 | ||
| 37 | int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, | ||
| 38 | struct radeon_cs_reloc **cs_reloc); | ||
| 37 | static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, | 39 | static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, |
| 38 | struct radeon_cs_reloc **cs_reloc); | 40 | struct radeon_cs_reloc **cs_reloc); |
| 39 | 41 | ||
| @@ -507,20 +509,28 @@ static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p, | |||
| 507 | /* height is npipes htiles aligned == npipes * 8 pixel aligned */ | 509 | /* height is npipes htiles aligned == npipes * 8 pixel aligned */ |
| 508 | nby = round_up(nby, track->npipes * 8); | 510 | nby = round_up(nby, track->npipes * 8); |
| 509 | } else { | 511 | } else { |
| 512 | /* always assume 8x8 htile */ | ||
| 513 | /* align is htile align * 8, htile align vary according to | ||
| 514 | * number of pipe and tile width and nby | ||
| 515 | */ | ||
| 510 | switch (track->npipes) { | 516 | switch (track->npipes) { |
| 511 | case 8: | 517 | case 8: |
| 518 | /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
| 512 | nbx = round_up(nbx, 64 * 8); | 519 | nbx = round_up(nbx, 64 * 8); |
| 513 | nby = round_up(nby, 64 * 8); | 520 | nby = round_up(nby, 64 * 8); |
| 514 | break; | 521 | break; |
| 515 | case 4: | 522 | case 4: |
| 523 | /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
| 516 | nbx = round_up(nbx, 64 * 8); | 524 | nbx = round_up(nbx, 64 * 8); |
| 517 | nby = round_up(nby, 32 * 8); | 525 | nby = round_up(nby, 32 * 8); |
| 518 | break; | 526 | break; |
| 519 | case 2: | 527 | case 2: |
| 528 | /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
| 520 | nbx = round_up(nbx, 32 * 8); | 529 | nbx = round_up(nbx, 32 * 8); |
| 521 | nby = round_up(nby, 32 * 8); | 530 | nby = round_up(nby, 32 * 8); |
| 522 | break; | 531 | break; |
| 523 | case 1: | 532 | case 1: |
| 533 | /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ | ||
| 524 | nbx = round_up(nbx, 32 * 8); | 534 | nbx = round_up(nbx, 32 * 8); |
| 525 | nby = round_up(nby, 16 * 8); | 535 | nby = round_up(nby, 16 * 8); |
| 526 | break; | 536 | break; |
| @@ -531,9 +541,10 @@ static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p, | |||
| 531 | } | 541 | } |
| 532 | } | 542 | } |
| 533 | /* compute number of htile */ | 543 | /* compute number of htile */ |
| 534 | nbx = nbx / 8; | 544 | nbx = nbx >> 3; |
| 535 | nby = nby / 8; | 545 | nby = nby >> 3; |
| 536 | size = nbx * nby * 4; | 546 | /* size must be aligned on npipes * 2K boundary */ |
| 547 | size = roundup(nbx * nby * 4, track->npipes * (2 << 10)); | ||
| 537 | size += track->htile_offset; | 548 | size += track->htile_offset; |
| 538 | 549 | ||
| 539 | if (size > radeon_bo_size(track->htile_bo)) { | 550 | if (size > radeon_bo_size(track->htile_bo)) { |
| @@ -1790,6 +1801,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 1790 | case DB_HTILE_SURFACE: | 1801 | case DB_HTILE_SURFACE: |
| 1791 | /* 8x8 only */ | 1802 | /* 8x8 only */ |
| 1792 | track->htile_surface = radeon_get_ib_value(p, idx); | 1803 | track->htile_surface = radeon_get_ib_value(p, idx); |
| 1804 | /* force 8x8 htile width and height */ | ||
| 1805 | ib[idx] |= 3; | ||
| 1793 | track->db_dirty = true; | 1806 | track->db_dirty = true; |
| 1794 | break; | 1807 | break; |
| 1795 | case CB_IMMED0_BASE: | 1808 | case CB_IMMED0_BASE: |
| @@ -2243,6 +2256,18 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
| 2243 | command = radeon_get_ib_value(p, idx+4); | 2256 | command = radeon_get_ib_value(p, idx+4); |
| 2244 | size = command & 0x1fffff; | 2257 | size = command & 0x1fffff; |
| 2245 | info = radeon_get_ib_value(p, idx+1); | 2258 | info = radeon_get_ib_value(p, idx+1); |
| 2259 | if ((((info & 0x60000000) >> 29) != 0) || /* src = GDS or DATA */ | ||
| 2260 | (((info & 0x00300000) >> 20) != 0) || /* dst = GDS */ | ||
| 2261 | ((((info & 0x00300000) >> 20) == 0) && | ||
| 2262 | (command & PACKET3_CP_DMA_CMD_DAS)) || /* dst = register */ | ||
| 2263 | ((((info & 0x60000000) >> 29) == 0) && | ||
| 2264 | (command & PACKET3_CP_DMA_CMD_SAS))) { /* src = register */ | ||
| 2265 | /* non mem to mem copies requires dw aligned count */ | ||
| 2266 | if (size % 4) { | ||
| 2267 | DRM_ERROR("CP DMA command requires dw count alignment\n"); | ||
| 2268 | return -EINVAL; | ||
| 2269 | } | ||
| 2270 | } | ||
| 2246 | if (command & PACKET3_CP_DMA_CMD_SAS) { | 2271 | if (command & PACKET3_CP_DMA_CMD_SAS) { |
| 2247 | /* src address space is register */ | 2272 | /* src address space is register */ |
| 2248 | /* GDS is ok */ | 2273 | /* GDS is ok */ |
| @@ -2804,6 +2829,455 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
| 2804 | return 0; | 2829 | return 0; |
| 2805 | } | 2830 | } |
| 2806 | 2831 | ||
| 2832 | /* | ||
| 2833 | * DMA | ||
| 2834 | */ | ||
| 2835 | |||
| 2836 | #define GET_DMA_CMD(h) (((h) & 0xf0000000) >> 28) | ||
| 2837 | #define GET_DMA_COUNT(h) ((h) & 0x000fffff) | ||
| 2838 | #define GET_DMA_T(h) (((h) & 0x00800000) >> 23) | ||
| 2839 | #define GET_DMA_NEW(h) (((h) & 0x04000000) >> 26) | ||
| 2840 | #define GET_DMA_MISC(h) (((h) & 0x0700000) >> 20) | ||
| 2841 | |||
| 2842 | /** | ||
| 2843 | * evergreen_dma_cs_parse() - parse the DMA IB | ||
| 2844 | * @p: parser structure holding parsing context. | ||
| 2845 | * | ||
| 2846 | * Parses the DMA IB from the CS ioctl and updates | ||
| 2847 | * the GPU addresses based on the reloc information and | ||
| 2848 | * checks for errors. (Evergreen-Cayman) | ||
| 2849 | * Returns 0 for success and an error on failure. | ||
| 2850 | **/ | ||
| 2851 | int evergreen_dma_cs_parse(struct radeon_cs_parser *p) | ||
| 2852 | { | ||
| 2853 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 2854 | struct radeon_cs_reloc *src_reloc, *dst_reloc, *dst2_reloc; | ||
| 2855 | u32 header, cmd, count, tiled, new_cmd, misc; | ||
| 2856 | volatile u32 *ib = p->ib.ptr; | ||
| 2857 | u32 idx, idx_value; | ||
| 2858 | u64 src_offset, dst_offset, dst2_offset; | ||
| 2859 | int r; | ||
| 2860 | |||
| 2861 | do { | ||
| 2862 | if (p->idx >= ib_chunk->length_dw) { | ||
| 2863 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", | ||
| 2864 | p->idx, ib_chunk->length_dw); | ||
| 2865 | return -EINVAL; | ||
| 2866 | } | ||
| 2867 | idx = p->idx; | ||
| 2868 | header = radeon_get_ib_value(p, idx); | ||
| 2869 | cmd = GET_DMA_CMD(header); | ||
| 2870 | count = GET_DMA_COUNT(header); | ||
| 2871 | tiled = GET_DMA_T(header); | ||
| 2872 | new_cmd = GET_DMA_NEW(header); | ||
| 2873 | misc = GET_DMA_MISC(header); | ||
| 2874 | |||
| 2875 | switch (cmd) { | ||
| 2876 | case DMA_PACKET_WRITE: | ||
| 2877 | r = r600_dma_cs_next_reloc(p, &dst_reloc); | ||
| 2878 | if (r) { | ||
| 2879 | DRM_ERROR("bad DMA_PACKET_WRITE\n"); | ||
| 2880 | return -EINVAL; | ||
| 2881 | } | ||
| 2882 | if (tiled) { | ||
| 2883 | dst_offset = ib[idx+1]; | ||
| 2884 | dst_offset <<= 8; | ||
| 2885 | |||
| 2886 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
| 2887 | p->idx += count + 7; | ||
