Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9add1ac3 authored by Dave Airlie's avatar Dave Airlie
Browse files

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
parents a636a982 86a1881d
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1821,7 +1821,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
	case CHIP_SUMO:
		rdev->config.evergreen.num_ses = 1;
		rdev->config.evergreen.max_pipes = 4;
		rdev->config.evergreen.max_tile_pipes = 2;
		rdev->config.evergreen.max_tile_pipes = 4;
		if (rdev->pdev->device == 0x9648)
			rdev->config.evergreen.max_simds = 3;
		else if ((rdev->pdev->device == 0x9647) ||
@@ -1844,7 +1844,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
		gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
		gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN;
		break;
	case CHIP_SUMO2:
		rdev->config.evergreen.num_ses = 1;
@@ -1866,7 +1866,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
		gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
		gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN;
		break;
	case CHIP_BARTS:
		rdev->config.evergreen.num_ses = 2;
@@ -1914,7 +1914,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
		break;
	case CHIP_CAICOS:
		rdev->config.evergreen.num_ses = 1;
		rdev->config.evergreen.max_pipes = 4;
		rdev->config.evergreen.max_pipes = 2;
		rdev->config.evergreen.max_tile_pipes = 2;
		rdev->config.evergreen.max_simds = 2;
		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
+136 −0
Original line number Diff line number Diff line
@@ -2232,6 +2232,95 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
			ib[idx+2] = upper_32_bits(offset) & 0xff;
		}
		break;
	case PACKET3_CP_DMA:
	{
		u32 command, size, info;
		u64 offset, tmp;
		if (pkt->count != 4) {
			DRM_ERROR("bad CP DMA\n");
			return -EINVAL;
		}
		command = radeon_get_ib_value(p, idx+4);
		size = command & 0x1fffff;
		info = radeon_get_ib_value(p, idx+1);
		if (command & PACKET3_CP_DMA_CMD_SAS) {
			/* src address space is register */
			/* GDS is ok */
			if (((info & 0x60000000) >> 29) != 1) {
				DRM_ERROR("CP DMA SAS not supported\n");
				return -EINVAL;
			}
		} else {
			if (command & PACKET3_CP_DMA_CMD_SAIC) {
				DRM_ERROR("CP DMA SAIC only supported for registers\n");
				return -EINVAL;
			}
			/* src address space is memory */
			if (((info & 0x60000000) >> 29) == 0) {
				r = evergreen_cs_packet_next_reloc(p, &reloc);
				if (r) {
					DRM_ERROR("bad CP DMA SRC\n");
					return -EINVAL;
				}

				tmp = radeon_get_ib_value(p, idx) +
					((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);

				offset = reloc->lobj.gpu_offset + tmp;

				if ((tmp + size) > radeon_bo_size(reloc->robj)) {
					dev_warn(p->dev, "CP DMA src buffer too small (%llu %lu)\n",
						 tmp + size, radeon_bo_size(reloc->robj));
					return -EINVAL;
				}

				ib[idx] = offset;
				ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
			} else if (((info & 0x60000000) >> 29) != 2) {
				DRM_ERROR("bad CP DMA SRC_SEL\n");
				return -EINVAL;
			}
		}
		if (command & PACKET3_CP_DMA_CMD_DAS) {
			/* dst address space is register */
			/* GDS is ok */
			if (((info & 0x00300000) >> 20) != 1) {
				DRM_ERROR("CP DMA DAS not supported\n");
				return -EINVAL;
			}
		} else {
			/* dst address space is memory */
			if (command & PACKET3_CP_DMA_CMD_DAIC) {
				DRM_ERROR("CP DMA DAIC only supported for registers\n");
				return -EINVAL;
			}
			if (((info & 0x00300000) >> 20) == 0) {
				r = evergreen_cs_packet_next_reloc(p, &reloc);
				if (r) {
					DRM_ERROR("bad CP DMA DST\n");
					return -EINVAL;
				}

				tmp = radeon_get_ib_value(p, idx+2) +
					((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32);

				offset = reloc->lobj.gpu_offset + tmp;

				if ((tmp + size) > radeon_bo_size(reloc->robj)) {
					dev_warn(p->dev, "CP DMA dst buffer too small (%llu %lu)\n",
						 tmp + size, radeon_bo_size(reloc->robj));
					return -EINVAL;
				}

				ib[idx+2] = offset;
				ib[idx+3] = upper_32_bits(offset) & 0xff;
			} else {
				DRM_ERROR("bad CP DMA DST_SEL\n");
				return -EINVAL;
			}
		}
		break;
	}
	case PACKET3_SURFACE_SYNC:
		if (pkt->count != 3) {
			DRM_ERROR("bad SURFACE_SYNC\n");
@@ -2843,6 +2932,7 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev,
	u32 idx = pkt->idx + 1;
	u32 idx_value = ib[idx];
	u32 start_reg, end_reg, reg, i;
	u32 command, info;

	switch (pkt->opcode) {
	case PACKET3_NOP:
@@ -2917,6 +3007,52 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev,
				return -EINVAL;
		}
		break;
	case PACKET3_CP_DMA:
		command = ib[idx + 4];
		info = ib[idx + 1];
		if (command & PACKET3_CP_DMA_CMD_SAS) {
			/* src address space is register */
			if (((info & 0x60000000) >> 29) == 0) {
				start_reg = idx_value << 2;
				if (command & PACKET3_CP_DMA_CMD_SAIC) {
					reg = start_reg;
					if (!evergreen_vm_reg_valid(reg)) {
						DRM_ERROR("CP DMA Bad SRC register\n");
						return -EINVAL;
					}
				} else {
					for (i = 0; i < (command & 0x1fffff); i++) {
						reg = start_reg + (4 * i);
						if (!evergreen_vm_reg_valid(reg)) {
							DRM_ERROR("CP DMA Bad SRC register\n");
							return -EINVAL;
						}
					}
				}
			}
		}
		if (command & PACKET3_CP_DMA_CMD_DAS) {
			/* dst address space is register */
			if (((info & 0x00300000) >> 20) == 0) {
				start_reg = ib[idx + 2];
				if (command & PACKET3_CP_DMA_CMD_DAIC) {
					reg = start_reg;
					if (!evergreen_vm_reg_valid(reg)) {
						DRM_ERROR("CP DMA Bad DST register\n");
						return -EINVAL;
					}
				} else {
					for (i = 0; i < (command & 0x1fffff); i++) {
						reg = start_reg + (4 * i);
						if (!evergreen_vm_reg_valid(reg)) {
							DRM_ERROR("CP DMA Bad DST register\n");
							return -EINVAL;
						}
					}
				}
			}
		}
		break;
	default:
		return -EINVAL;
	}
+49 −0
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@
#define TURKS_GB_ADDR_CONFIG_GOLDEN          0x02010002
#define CEDAR_GB_ADDR_CONFIG_GOLDEN          0x02010001
#define CAICOS_GB_ADDR_CONFIG_GOLDEN         0x02010001
#define SUMO_GB_ADDR_CONFIG_GOLDEN           0x02010002
#define SUMO2_GB_ADDR_CONFIG_GOLDEN          0x02010002

/* Registers */

@@ -1033,6 +1035,53 @@
#define	PACKET3_WAIT_REG_MEM				0x3C
#define	PACKET3_MEM_WRITE				0x3D
#define	PACKET3_INDIRECT_BUFFER				0x32
#define	PACKET3_CP_DMA					0x41
/* 1. header
 * 2. SRC_ADDR_LO or DATA [31:0]
 * 3. CP_SYNC [31] | SRC_SEL [30:29] | ENGINE [27] | DST_SEL [21:20] |
 *    SRC_ADDR_HI [7:0]
 * 4. DST_ADDR_LO [31:0]
 * 5. DST_ADDR_HI [7:0]
 * 6. COMMAND [29:22] | BYTE_COUNT [20:0]
 */
#              define PACKET3_CP_DMA_DST_SEL(x)    ((x) << 20)
                /* 0 - SRC_ADDR
		 * 1 - GDS
		 */
#              define PACKET3_CP_DMA_ENGINE(x)     ((x) << 27)
                /* 0 - ME
		 * 1 - PFP
		 */
#              define PACKET3_CP_DMA_SRC_SEL(x)    ((x) << 29)
                /* 0 - SRC_ADDR
		 * 1 - GDS
		 * 2 - DATA
		 */
#              define PACKET3_CP_DMA_CP_SYNC       (1 << 31)
/* COMMAND */
#              define PACKET3_CP_DMA_DIS_WC        (1 << 21)
#              define PACKET3_CP_DMA_CMD_SRC_SWAP(x) ((x) << 23)
                /* 0 - none
		 * 1 - 8 in 16
		 * 2 - 8 in 32
		 * 3 - 8 in 64
		 */
#              define PACKET3_CP_DMA_CMD_DST_SWAP(x) ((x) << 24)
                /* 0 - none
		 * 1 - 8 in 16
		 * 2 - 8 in 32
		 * 3 - 8 in 64
		 */
#              define PACKET3_CP_DMA_CMD_SAS       (1 << 26)
                /* 0 - memory
		 * 1 - register
		 */
#              define PACKET3_CP_DMA_CMD_DAS       (1 << 27)
                /* 0 - memory
		 * 1 - register
		 */
#              define PACKET3_CP_DMA_CMD_SAIC      (1 << 28)
#              define PACKET3_CP_DMA_CMD_DAIC      (1 << 29)
#define	PACKET3_SURFACE_SYNC				0x43
#              define PACKET3_CB0_DEST_BASE_ENA    (1 << 6)
#              define PACKET3_CB1_DEST_BASE_ENA    (1 << 7)
+2 −1
Original line number Diff line number Diff line
@@ -2533,11 +2533,12 @@ void r600_dma_fence_ring_emit(struct radeon_device *rdev,
{
	struct radeon_ring *ring = &rdev->ring[fence->ring];
	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;

	/* write the fence */
	radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0));
	radeon_ring_write(ring, addr & 0xfffffffc);
	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff));
	radeon_ring_write(ring, fence->seq);
	radeon_ring_write(ring, lower_32_bits(fence->seq));
	/* generate an interrupt */
	radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0));
}
+72 −0
Original line number Diff line number Diff line
@@ -1949,6 +1949,78 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
			ib[idx+2] = upper_32_bits(offset) & 0xff;
		}
		break;
	case PACKET3_CP_DMA:
	{
		u32 command, size;
		u64 offset, tmp;
		if (pkt->count != 4) {
			DRM_ERROR("bad CP DMA\n");
			return -EINVAL;
		}
		command = radeon_get_ib_value(p, idx+4);
		size = command & 0x1fffff;
		if (command & PACKET3_CP_DMA_CMD_SAS) {
			/* src address space is register */
			DRM_ERROR("CP DMA SAS not supported\n");
			return -EINVAL;
		} else {
			if (command & PACKET3_CP_DMA_CMD_SAIC) {
				DRM_ERROR("CP DMA SAIC only supported for registers\n");
				return -EINVAL;
			}
			/* src address space is memory */
			r = r600_cs_packet_next_reloc(p, &reloc);
			if (r) {
				DRM_ERROR("bad CP DMA SRC\n");
				return -EINVAL;
			}

			tmp = radeon_get_ib_value(p, idx) +
				((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);

			offset = reloc->lobj.gpu_offset + tmp;

			if ((tmp + size) > radeon_bo_size(reloc->robj)) {
				dev_warn(p->dev, "CP DMA src buffer too small (%llu %lu)\n",
					 tmp + size, radeon_bo_size(reloc->robj));
				return -EINVAL;
			}

			ib[idx] = offset;
			ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
		}
		if (command & PACKET3_CP_DMA_CMD_DAS) {
			/* dst address space is register */
			DRM_ERROR("CP DMA DAS not supported\n");
			return -EINVAL;
		} else {
			/* dst address space is memory */
			if (command & PACKET3_CP_DMA_CMD_DAIC) {
				DRM_ERROR("CP DMA DAIC only supported for registers\n");
				return -EINVAL;
			}
			r = r600_cs_packet_next_reloc(p, &reloc);
			if (r) {
				DRM_ERROR("bad CP DMA DST\n");
				return -EINVAL;
			}

			tmp = radeon_get_ib_value(p, idx+2) +
				((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32);

			offset = reloc->lobj.gpu_offset + tmp;

			if ((tmp + size) > radeon_bo_size(reloc->robj)) {
				dev_warn(p->dev, "CP DMA dst buffer too small (%llu %lu)\n",
					 tmp + size, radeon_bo_size(reloc->robj));
				return -EINVAL;
			}

			ib[idx+2] = offset;
			ib[idx+3] = upper_32_bits(offset) & 0xff;
		}
		break;
	}
	case PACKET3_SURFACE_SYNC:
		if (pkt->count != 3) {
			DRM_ERROR("bad SURFACE_SYNC\n");
Loading