diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-12-03 19:03:23 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-12-12 17:16:49 -0500 |
commit | 6830f585724e1db5609dab0b059ea2e338bd9cc2 (patch) | |
tree | 051ee0e6d81b5f66db783a1d650d11ef35fdd474 | |
parent | b997a8ba26377895506a26a3f2b8f1e7abc4ed22 (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.c | 72 |
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"); |