diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-12-03 19:18:30 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-12-12 17:16:49 -0500 |
commit | 8770b86b3e02c3e30f2ffc42753ff9d62bc428bf (patch) | |
tree | 2f7a5b0a178f0f447190d748903b52ca43ebd527 /drivers/gpu/drm/radeon/evergreen_cs.c | |
parent | 6830f585724e1db5609dab0b059ea2e338bd9cc2 (diff) |
drm/radeon: add support for CP DMA packet to evergreen CS checker
Currently only memory and GDS transfers are allowed.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index c042e497e450..5435879ad535 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -2232,6 +2232,95 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2232 | ib[idx+2] = upper_32_bits(offset) & 0xff; | 2232 | ib[idx+2] = upper_32_bits(offset) & 0xff; |
2233 | } | 2233 | } |
2234 | break; | 2234 | break; |
2235 | case PACKET3_CP_DMA: | ||
2236 | { | ||
2237 | u32 command, size, info; | ||
2238 | u64 offset, tmp; | ||
2239 | if (pkt->count != 4) { | ||
2240 | DRM_ERROR("bad CP DMA\n"); | ||
2241 | return -EINVAL; | ||
2242 | } | ||
2243 | command = radeon_get_ib_value(p, idx+4); | ||
2244 | size = command & 0x1fffff; | ||
2245 | info = radeon_get_ib_value(p, idx+1); | ||
2246 | if (command & PACKET3_CP_DMA_CMD_SAS) { | ||
2247 | /* src address space is register */ | ||
2248 | /* GDS is ok */ | ||
2249 | if (((info & 0x60000000) >> 29) != 1) { | ||
2250 | DRM_ERROR("CP DMA SAS not supported\n"); | ||
2251 | return -EINVAL; | ||
2252 | } | ||
2253 | } else { | ||
2254 | if (command & PACKET3_CP_DMA_CMD_SAIC) { | ||
2255 | DRM_ERROR("CP DMA SAIC only supported for registers\n"); | ||
2256 | return -EINVAL; | ||
2257 | } | ||
2258 | /* src address space is memory */ | ||
2259 | if (((info & 0x60000000) >> 29) == 0) { | ||
2260 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2261 | if (r) { | ||
2262 | DRM_ERROR("bad CP DMA SRC\n"); | ||
2263 | return -EINVAL; | ||
2264 | } | ||
2265 | |||
2266 | tmp = radeon_get_ib_value(p, idx) + | ||
2267 | ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); | ||
2268 | |||
2269 | offset = reloc->lobj.gpu_offset + tmp; | ||
2270 | |||
2271 | if ((tmp + size) > radeon_bo_size(reloc->robj)) { | ||
2272 | dev_warn(p->dev, "CP DMA src buffer too small (%llu %lu)\n", | ||
2273 | tmp + size, radeon_bo_size(reloc->robj)); | ||
2274 | return -EINVAL; | ||
2275 | } | ||
2276 | |||
2277 | ib[idx] = offset; | ||
2278 | ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff); | ||
2279 | } else if (((info & 0x60000000) >> 29) != 2) { | ||
2280 | DRM_ERROR("bad CP DMA SRC_SEL\n"); | ||
2281 | return -EINVAL; | ||
2282 | } | ||
2283 | } | ||
2284 | if (command & PACKET3_CP_DMA_CMD_DAS) { | ||
2285 | /* dst address space is register */ | ||
2286 | /* GDS is ok */ | ||
2287 | if (((info & 0x00300000) >> 20) != 1) { | ||
2288 | DRM_ERROR("CP DMA DAS not supported\n"); | ||
2289 | return -EINVAL; | ||
2290 | } | ||
2291 | } else { | ||
2292 | /* dst address space is memory */ | ||
2293 | if (command & PACKET3_CP_DMA_CMD_DAIC) { | ||
2294 | DRM_ERROR("CP DMA DAIC only supported for registers\n"); | ||
2295 | return -EINVAL; | ||
2296 | } | ||
2297 | if (((info & 0x00300000) >> 20) == 0) { | ||
2298 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2299 | if (r) { | ||
2300 | DRM_ERROR("bad CP DMA DST\n"); | ||
2301 | return -EINVAL; | ||
2302 | } | ||
2303 | |||
2304 | tmp = radeon_get_ib_value(p, idx+2) + | ||
2305 | ((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32); | ||
2306 | |||
2307 | offset = reloc->lobj.gpu_offset + tmp; | ||
2308 | |||
2309 | if ((tmp + size) > radeon_bo_size(reloc->robj)) { | ||
2310 | dev_warn(p->dev, "CP DMA dst buffer too small (%llu %lu)\n", | ||
2311 | tmp + size, radeon_bo_size(reloc->robj)); | ||
2312 | return -EINVAL; | ||
2313 | } | ||
2314 | |||
2315 | ib[idx+2] = offset; | ||
2316 | ib[idx+3] = upper_32_bits(offset) & 0xff; | ||
2317 | } else { | ||
2318 | DRM_ERROR("bad CP DMA DST_SEL\n"); | ||
2319 | return -EINVAL; | ||
2320 | } | ||
2321 | } | ||
2322 | break; | ||
2323 | } | ||
2235 | case PACKET3_SURFACE_SYNC: | 2324 | case PACKET3_SURFACE_SYNC: |
2236 | if (pkt->count != 3) { | 2325 | if (pkt->count != 3) { |
2237 | DRM_ERROR("bad SURFACE_SYNC\n"); | 2326 | DRM_ERROR("bad SURFACE_SYNC\n"); |