diff options
| -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"); |
