aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-12-03 19:03:23 -0500
committerAlex Deucher <alexander.deucher@amd.com>2012-12-12 17:16:49 -0500
commit6830f585724e1db5609dab0b059ea2e338bd9cc2 (patch)
tree051ee0e6d81b5f66db783a1d650d11ef35fdd474
parentb997a8ba26377895506a26a3f2b8f1e7abc4ed22 (diff)
drm/radeon: add support for CP DMA packet to r6xx/r7xx CS checker
Currently only memory to memory transfers are allowed. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c72
1 files changed, 72 insertions, 0 deletions
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");