From patchwork Thu Dec 13 17:57:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 1875781 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 72CE23FC81 for ; Thu, 13 Dec 2012 18:00:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 60385E5C6B for ; Thu, 13 Dec 2012 10:00:29 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-vb0-f49.google.com (mail-vb0-f49.google.com [209.85.212.49]) by gabe.freedesktop.org (Postfix) with ESMTP id 35C8BE5C6C for ; Thu, 13 Dec 2012 09:58:02 -0800 (PST) Received: by mail-vb0-f49.google.com with SMTP id r6so2749605vbi.36 for ; Thu, 13 Dec 2012 09:58:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=0AZq68maBylhiq6S+ns0kceA9jn6TgABy0wRhZ2QYO4=; b=O9Cp+f9Go5xVAgXZE6QV4iEA1MQAZBJ2H73EVzmvMWUImkPJ68dHFTCmu36PflK7d1 Lxy+0WitdglobvXwvDkRlR/zqsDXGkrPIy/x9TnZSTRT2aKxFH4hPzKcJ0g9fpz875nG aDWMVAJRdn6hrdf0mVmNGRW3L0hb+GITQnZgpDcyPhU6tcJPs6S+jAALES8pKifcOX5L z1TXdOYpFjBt1OCCqBWqhx+ShIDIB7HNFnJ91MgcQRQThXfTrkTTsdDbKxKUPgIdz+T3 TXtkdRHYdWL0Z1Hq/jpP1o6MfJpPelQJrylTe+i8yPkjlCvcVmNqzqlXWMm1y+1/ufol tZIg== Received: by 10.52.18.147 with SMTP id w19mr4204366vdd.94.1355421481745; Thu, 13 Dec 2012 09:58:01 -0800 (PST) Received: from localhost.localdomain (static-74-96-105-49.washdc.fios.verizon.net. [74.96.105.49]) by mx.google.com with ESMTPS id jx16sm1600635veb.5.2012.12.13.09.58.00 (version=SSLv3 cipher=OTHER); Thu, 13 Dec 2012 09:58:01 -0800 (PST) From: alexdeucher@gmail.com To: airlied@gmail.com, dri-devel@lists.freedesktop.org Subject: [PATCH 3/4] drm/radeon: add VM CS parser support for async DMA on cayman/TN/SI Date: Thu, 13 Dec 2012 12:57:50 -0500 Message-Id: <1355421471-6166-3-git-send-email-alexdeucher@gmail.com> X-Mailer: git-send-email 1.7.7.5 In-Reply-To: <1355421471-6166-1-git-send-email-alexdeucher@gmail.com> References: <1355421471-6166-1-git-send-email-alexdeucher@gmail.com> Cc: Alex Deucher X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: Alex Deucher Allows us to use async DMA from userspace. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_cs.c | 111 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_asic.c | 6 ++ drivers/gpu/drm/radeon/radeon_asic.h | 1 + 3 files changed, 118 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index adfc66f..fefb2cc 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -3543,3 +3543,114 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) return ret; } + +/** + * evergreen_dma_ib_parse() - parse the DMA IB for VM + * @rdev: radeon_device pointer + * @ib: radeon_ib pointer + * + * Parses the DMA IB from the VM CS ioctl + * checks for errors. (Cayman-SI) + * Returns 0 for success and an error on failure. + **/ +int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) +{ + u32 idx = 0; + u32 header, cmd, count, tiled, new_cmd, misc; + + do { + header = ib->ptr[idx]; + cmd = GET_DMA_CMD(header); + count = GET_DMA_COUNT(header); + tiled = GET_DMA_T(header); + new_cmd = GET_DMA_NEW(header); + misc = GET_DMA_MISC(header); + + switch (cmd) { + case DMA_PACKET_WRITE: + if (tiled) + idx += count + 7; + else + idx += count + 3; + break; + case DMA_PACKET_COPY: + if (tiled) { + if (new_cmd) { + switch (misc) { + case 0: + /* L2T, frame to fields */ + idx += 10; + break; + case 1: + /* L2T, T2L partial */ + idx += 12; + break; + case 3: + /* L2T, broadcast */ + idx += 10; + break; + case 4: + /* L2T, T2L */ + idx += 9; + break; + case 5: + /* T2T partial */ + idx += 13; + break; + case 7: + /* L2T, broadcast */ + idx += 10; + break; + default: + DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); + return -EINVAL; + } + } else { + switch (misc) { + case 0: + idx += 9; + break; + default: + DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); + return -EINVAL; + } + } + } else { + if (new_cmd) { + switch (misc) { + case 0: + /* L2L, byte */ + idx += 5; + break; + case 1: + /* L2L, partial */ + idx += 9; + break; + case 4: + /* L2L, dw, broadcast */ + idx += 7; + break; + default: + DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); + return -EINVAL; + } + } else { + /* L2L, dw */ + idx += 5; + } + } + break; + case DMA_PACKET_CONSTANT_FILL: + idx += 4; + break; + case DMA_PACKET_NOP: + idx += 1; + break; + default: + DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx); + return -EINVAL; + } + } while (idx < ib->length_dw); + + return 0; +} diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index ac1d570..596bcbe 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1484,6 +1484,7 @@ static struct radeon_asic cayman_asic = { }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &cayman_dma_ring_ib_execute, + .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, .cs_parse = &evergreen_dma_cs_parse, @@ -1494,6 +1495,7 @@ static struct radeon_asic cayman_asic = { }, [CAYMAN_RING_TYPE_DMA1_INDEX] = { .ib_execute = &cayman_dma_ring_ib_execute, + .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, .cs_parse = &evergreen_dma_cs_parse, @@ -1609,6 +1611,7 @@ static struct radeon_asic trinity_asic = { }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &cayman_dma_ring_ib_execute, + .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, .cs_parse = &evergreen_dma_cs_parse, @@ -1619,6 +1622,7 @@ static struct radeon_asic trinity_asic = { }, [CAYMAN_RING_TYPE_DMA1_INDEX] = { .ib_execute = &cayman_dma_ring_ib_execute, + .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, .cs_parse = &evergreen_dma_cs_parse, @@ -1734,6 +1738,7 @@ static struct radeon_asic si_asic = { }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &cayman_dma_ring_ib_execute, + .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, .cs_parse = NULL, @@ -1744,6 +1749,7 @@ static struct radeon_asic si_asic = { }, [CAYMAN_RING_TYPE_DMA1_INDEX] = { .ib_execute = &cayman_dma_ring_ib_execute, + .ib_parse = &evergreen_dma_ib_parse, .emit_fence = &evergreen_dma_fence_ring_emit, .emit_semaphore = &r600_dma_semaphore_ring_emit, .cs_parse = NULL, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index d2ac646..5f4882c 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -473,6 +473,7 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags); int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); +int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); void cayman_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);