From patchwork Fri Aug 10 14:57:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maarten Lankhorst X-Patchwork-Id: 10684 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id CE14223E41 for ; Fri, 10 Aug 2012 14:58:02 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id 86E07A1914E for ; Fri, 10 Aug 2012 14:58:02 +0000 (UTC) Received: by yenq6 with SMTP id q6so1667344yen.11 for ; Fri, 10 Aug 2012 07:58:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:subject:to :from:cc:date:message-id:in-reply-to:references:user-agent :mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=5nJXntUk7pAKvNm7K2mWDrrtYsEIzso0jAcTvm8dsPY=; b=SVIIsn12HX/RtpN1B34l+mvdcuu/YwePK5X9s+0UY1gXcz1NBcGrjQnRRzHKMzV+Ho a7AOOuw8ADFzs4ljBldqdffNhm/+Fp1KBvUy5Pv5ly5aAFO9a2H4+RNE0xFXJ32JCyfk RC00C+J8meVrzU1Lhk5m/wB2wGyndBU1JF6ZW7tgeBdfD7p1HMEK3+20eCV5h3zpA4jo ivcSFNYpJ3ktsCkUIVkpF8USMI38t8HPj3GwQZuafHC1Bpk69oYvwWgAP+Te8044yFmr pcQ9JhF7wmQyeHitMuOi2TxPhFKVF1qsq114O+0xCCuLSIcLW9RJp/ndFrT/118xLv1Q GQnQ== Received: by 10.50.170.3 with SMTP id ai3mr2096960igc.9.1344610681649; Fri, 10 Aug 2012 07:58:01 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.200 with SMTP id ew8csp65162igc; Fri, 10 Aug 2012 07:58:00 -0700 (PDT) Received: by 10.180.91.1 with SMTP id ca1mr6701701wib.8.1344610680569; Fri, 10 Aug 2012 07:58:00 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com. [91.189.90.139]) by mx.google.com with ESMTP id w20si5981624wec.144.2012.08.10.07.58.00; Fri, 10 Aug 2012 07:58:00 -0700 (PDT) Received-SPF: pass (google.com: domain of mlankhorst@lillypilly.canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: domain of mlankhorst@lillypilly.canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=mlankhorst@lillypilly.canonical.com Received: from lillypilly.canonical.com ([91.189.89.62]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1Szqf1-0006bI-OI; Fri, 10 Aug 2012 14:57:59 +0000 Received: by lillypilly.canonical.com (Postfix, from userid 3489) id B372A26C26C6; Fri, 10 Aug 2012 14:57:59 +0000 (UTC) Subject: [PATCH 3/4] dma-seqno-fence: Hardware dma-buf implementation of fencing (v2) To: sumit.semwal@linaro.org, rob.clark@linaro.org From: Maarten Lankhorst Cc: linaro-mm-sig@lists.linaro.org, linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, patches@linaro.org Date: Fri, 10 Aug 2012 16:57:58 +0200 Message-ID: <20120810145758.5490.62372.stgit@patser.local> In-Reply-To: <20120810145728.5490.44707.stgit@patser.local> References: <20120810145728.5490.44707.stgit@patser.local> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQnKDD5hojLHc5xh0CSrDXTRdv/DEvrv9ht6NwoRWk/PJAB3ihP0Ql4NaCX2IFHiLki4vkgo This type of fence can be used with hardware synchronization for simple hardware that can block execution until the condition (dma_buf[offset] - value) >= 0 has been met. A software fallback still has to be provided in case the fence is used with a device that doesn't support this mechanism. It is useful to expose this for graphics cards that have an op to support this. Some cards like i915 can export those, but don't have an option to wait, so they need the software fallback. I extended the original patch by Rob Clark. v1: Original v2: Renamed from bikeshed to seqno, moved into dma-fence.c since not much was left of the file. Lots of documentation added. Signed-off-by: Maarten Lankhorst Reviewed-by: Daniel Vetter --- drivers/base/dma-fence.c | 21 +++++++++++++++ include/linux/dma-fence.h | 61 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/drivers/base/dma-fence.c b/drivers/base/dma-fence.c index 93448e4..4092a58 100644 --- a/drivers/base/dma-fence.c +++ b/drivers/base/dma-fence.c @@ -266,3 +266,24 @@ struct dma_fence *dma_fence_create(void *priv) return fence; } EXPORT_SYMBOL_GPL(dma_fence_create); + +static int seqno_enable_signaling(struct dma_fence *fence) +{ + struct dma_seqno_fence *seqno_fence = to_seqno_fence(fence); + return seqno_fence->enable_signaling(seqno_fence); +} + +static void seqno_release(struct dma_fence *fence) +{ + struct dma_seqno_fence *f = to_seqno_fence(fence); + + if (f->release) + f->release(f); + dma_buf_put(f->sync_buf); +} + +const struct dma_fence_ops dma_seqno_fence_ops = { + .enable_signaling = seqno_enable_signaling, + .release = seqno_release +}; +EXPORT_SYMBOL_GPL(dma_seqno_fence_ops); diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index e0ceddd..3ef0da0 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -91,6 +91,19 @@ struct dma_fence_ops { void (*release)(struct dma_fence *fence); }; +struct dma_seqno_fence { + struct dma_fence base; + + struct dma_buf *sync_buf; + uint32_t seqno_ofs; + uint32_t seqno; + + int (*enable_signaling)(struct dma_seqno_fence *fence); + void (*release)(struct dma_seqno_fence *fence); +}; + +extern const struct dma_fence_ops dma_seqno_fence_ops; + struct dma_fence *dma_fence_create(void *priv); /** @@ -121,4 +134,52 @@ int dma_fence_wait(struct dma_fence *fence, bool intr, unsigned long timeout); int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb, dma_fence_func_t func, void *priv); +/** + * to_seqno_fence - cast a dma_fence to a dma_seqno_fence + * @fence: dma_fence to cast to a dma_seqno_fence + * + * Returns NULL if the dma_fence is not a dma_seqno_fence, + * or the dma_seqno_fence otherwise. + */ +static inline struct dma_seqno_fence * +to_seqno_fence(struct dma_fence *fence) +{ + if (fence->ops != &dma_seqno_fence_ops) + return NULL; + return container_of(fence, struct dma_seqno_fence, base); +} + +/** + * dma_seqno_fence_init - initialize a seqno fence + * @fence: dma_seqno_fence to initialize + * @sync_buf: buffer containing the memory location to signal on + * @seqno_ofs: the offset within @sync_buf + * @seqno: the sequence # to signal on + * @priv: value of priv member + * @enable_signaling: callback which is called when some other device is + * waiting for sw notification of fence + * @release: callback called during destruction before object is freed. + * + * This function initializes a struct dma_seqno_fence with passed parameters, + * and takes a reference on sync_buf which is released on fence destruction. + */ +static inline void +dma_seqno_fence_init(struct dma_seqno_fence *fence, + struct dma_buf *sync_buf, + uint32_t seqno_ofs, uint32_t seqno, void *priv, + int (*enable_signaling)(struct dma_seqno_fence *), + void (*release)(struct dma_seqno_fence *)) +{ + BUG_ON(!fence || !sync_buf || !enable_signaling); + + __dma_fence_init(&fence->base, &dma_seqno_fence_ops, priv); + + get_dma_buf(sync_buf); + fence->sync_buf = sync_buf; + fence->seqno_ofs = seqno_ofs; + fence->seqno = seqno; + fence->enable_signaling = enable_signaling; + fence->release = release; +} + #endif /* __DMA_FENCE_H__ */