From patchwork Thu Sep 15 18:30:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Longerbeam X-Patchwork-Id: 9334961 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DD148607FD for ; Fri, 16 Sep 2016 01:11:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE39629E7F for ; Fri, 16 Sep 2016 01:11:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C2A5629E82; Fri, 16 Sep 2016 01:11:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1635329E7F for ; Fri, 16 Sep 2016 01:11:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 10EE26E982; Fri, 16 Sep 2016 01:11:21 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pa0-x243.google.com (mail-pa0-x243.google.com [IPv6:2607:f8b0:400e:c03::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id D655F6E906 for ; Thu, 15 Sep 2016 18:31:04 +0000 (UTC) Received: by mail-pa0-x243.google.com with SMTP id oz2so2400698pac.0 for ; Thu, 15 Sep 2016 11:31:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6DkvBuq2d0my7eMtGE9TXwd2FPB1YvphFehJ/6ZtS7E=; b=p660KnIGYSbm7g1ls1ybWsFgV2Wbbj3uAVX4gCe34PYISxJ+VaPkp8dZKX6lYhZyMg Y4xgPk8qlC8sckzlDcOe/MSdX/ueG++IRb+mk5UVY51alTkqHEDyLvm7cb0cW8DhC652 7c51JNZS9RzygKORfia0ibYOWaEVPXv+mSwLZalLw14euHwJn2pIBfBaU1QxxgAqlPci jR0mMfPvLRYG9bo3igW6k8IlGcV7rHZ7sSNJHw289eVeLvrI6xNfZxIz/MkHa03HZ3Xw +G6CzsMDfN7t/NLGV4FSPzf3EqW9nirxqM1JPtiYOEj2fyQjFqD6o+1dMFnYfE8qv13w ZRMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6DkvBuq2d0my7eMtGE9TXwd2FPB1YvphFehJ/6ZtS7E=; b=cL8wz5KRAqKvXuWVDqiOMgcIDd2BGewgG46T8VgDDLtKimizBkE2n0NAQ8LyIDKk0D tNE6uG390rqQHqCrLmZ3Me2S4XWrlBeLFoHevnJ43HWVUnrvNWS3leEWlvZzfIwAis3j bLYvur82jMIMPivKkyGjIm0eawOQrDmc5d4tc8iwRyiCvpQL5X5KMgH+Hek53DhkasZj 2997lu3VzZ4r/bUpsw5D6xRPze4p+o9ahkReKfWfbUG0n8vpKzLdXz00kpvxuZb70vIZ UPl1IqRYvwPYDseXhe642BT6c2ZF23MeneIYMjQRmA5l+ETqzxZPlEXICp0/hnBhjioS h/RQ== X-Gm-Message-State: AE9vXwNvSafBnh9TElU8HQNmYJiU3WScbYXyOiEkVTzHeLhJsI7d0qIQbbxmOS5Jpcg1Zg== X-Received: by 10.66.255.42 with SMTP id an10mr16904918pad.57.1473964263627; Thu, 15 Sep 2016 11:31:03 -0700 (PDT) Received: from majic.world.mentorg.com (c-73-241-2-21.hsd1.ca.comcast.net. [73.241.2.21]) by smtp.googlemail.com with ESMTPSA id yu7sm6680554pab.45.2016.09.15.11.31.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 15 Sep 2016 11:31:03 -0700 (PDT) From: Steve Longerbeam X-Google-Original-From: Steve Longerbeam To: p.zabel@pengutronix.de, tomi.valkeinen@ti.com Subject: [PATCH v6 1/3] gpu: ipu-v3: Add FSU channel linking support Date: Thu, 15 Sep 2016 11:30:49 -0700 Message-Id: <1473964251-20662-2-git-send-email-steve_longerbeam@mentor.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1473964251-20662-1-git-send-email-steve_longerbeam@mentor.com> References: <1473964251-20662-1-git-send-email-steve_longerbeam@mentor.com> X-Mailman-Approved-At: Fri, 16 Sep 2016 01:09:16 +0000 Cc: linux-fbdev@vger.kernel.org, Steve Longerbeam , dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Adds functions to link and unlink source channels to sink channels in the FSU: int ipu_fsu_link(struct ipu_soc *ipu, int src_ch, int sink_ch); int ipu_fsu_unlink(struct ipu_soc *ipu, int src_ch, int sink_ch); The channels numbers are usually IDMAC channels, but they can also be channels that do not transfer data to or from memory. The following convenience functions can be used in place of ipu_fsu_link/unlink() when both source and sink channels are IDMAC channels: int ipu_idmac_link(struct ipuv3_channel *src, struct ipuv3_channel *sink); int ipu_idmac_unlink(struct ipuv3_channel *src, struct ipuv3_channel *sink); So far the following links are supported: IPUV3_CHANNEL_IC_PRP_ENC_MEM -> IPUV3_CHANNEL_MEM_ROT_ENC PUV3_CHANNEL_IC_PRP_VF_MEM -> IPUV3_CHANNEL_MEM_ROT_VF IPUV3_CHANNEL_IC_PP_MEM -> IPUV3_CHANNEL_MEM_ROT_PP IPUV3_CHANNEL_CSI_DIRECT -> IPUV3_CHANNEL_CSI_VDI_PREV More links can be added to the fsu_link_info[] array. Signed-off-by: Steve Longerbeam --- drivers/gpu/ipu-v3/ipu-common.c | 131 ++++++++++++++++++++++++++++++++++++++++ drivers/gpu/ipu-v3/ipu-prv.h | 27 +++++++++ include/video/imx-ipu-v3.h | 13 ++++ 3 files changed, 171 insertions(+) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index d230988..fe389dd 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -730,6 +730,137 @@ void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi) } EXPORT_SYMBOL_GPL(ipu_set_ic_src_mux); + +/* Frame Synchronization Unit Channel Linking */ + +struct fsu_link_reg_info { + int chno; + u32 reg; + u32 mask; + u32 val; +}; + +struct fsu_link_info { + struct fsu_link_reg_info src; + struct fsu_link_reg_info sink; +}; + +static const struct fsu_link_info fsu_link_info[] = { + { + .src = { IPUV3_CHANNEL_IC_PRP_ENC_MEM, IPU_FS_PROC_FLOW2, + FS_PRP_ENC_DEST_SEL_MASK, FS_PRP_ENC_DEST_SEL_IRT_ENC }, + .sink = { IPUV3_CHANNEL_MEM_ROT_ENC, IPU_FS_PROC_FLOW1, + FS_PRPENC_ROT_SRC_SEL_MASK, FS_PRPENC_ROT_SRC_SEL_ENC }, + }, { + .src = { IPUV3_CHANNEL_IC_PRP_VF_MEM, IPU_FS_PROC_FLOW2, + FS_PRPVF_DEST_SEL_MASK, FS_PRPVF_DEST_SEL_IRT_VF }, + .sink = { IPUV3_CHANNEL_MEM_ROT_VF, IPU_FS_PROC_FLOW1, + FS_PRPVF_ROT_SRC_SEL_MASK, FS_PRPVF_ROT_SRC_SEL_VF }, + }, { + .src = { IPUV3_CHANNEL_IC_PP_MEM, IPU_FS_PROC_FLOW2, + FS_PP_DEST_SEL_MASK, FS_PP_DEST_SEL_IRT_PP }, + .sink = { IPUV3_CHANNEL_MEM_ROT_PP, IPU_FS_PROC_FLOW1, + FS_PP_ROT_SRC_SEL_MASK, FS_PP_ROT_SRC_SEL_PP }, + }, { + .src = { IPUV3_CHANNEL_CSI_DIRECT, 0 }, + .sink = { IPUV3_CHANNEL_CSI_VDI_PREV, IPU_FS_PROC_FLOW1, + FS_VDI_SRC_SEL_MASK, FS_VDI_SRC_SEL_CSI_DIRECT }, + }, +}; + +static const struct fsu_link_info *find_fsu_link_info(int src, int sink) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fsu_link_info); i++) { + if (src == fsu_link_info[i].src.chno && + sink == fsu_link_info[i].sink.chno) + return &fsu_link_info[i]; + } + + return NULL; +} + +/* + * Links a source channel to a sink channel in the FSU. + */ +int ipu_fsu_link(struct ipu_soc *ipu, int src_ch, int sink_ch) +{ + const struct fsu_link_info *link; + u32 src_reg, sink_reg; + unsigned long flags; + + link = find_fsu_link_info(src_ch, sink_ch); + if (!link) + return -EINVAL; + + spin_lock_irqsave(&ipu->lock, flags); + + if (link->src.mask) { + src_reg = ipu_cm_read(ipu, link->src.reg); + src_reg &= ~link->src.mask; + src_reg |= link->src.val; + ipu_cm_write(ipu, src_reg, link->src.reg); + } + + if (link->sink.mask) { + sink_reg = ipu_cm_read(ipu, link->sink.reg); + sink_reg &= ~link->sink.mask; + sink_reg |= link->sink.val; + ipu_cm_write(ipu, sink_reg, link->sink.reg); + } + + spin_unlock_irqrestore(&ipu->lock, flags); + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fsu_link); + +/* + * Unlinks source and sink channels in the FSU. + */ +int ipu_fsu_unlink(struct ipu_soc *ipu, int src_ch, int sink_ch) +{ + const struct fsu_link_info *link; + u32 src_reg, sink_reg; + unsigned long flags; + + link = find_fsu_link_info(src_ch, sink_ch); + if (!link) + return -EINVAL; + + spin_lock_irqsave(&ipu->lock, flags); + + if (link->src.mask) { + src_reg = ipu_cm_read(ipu, link->src.reg); + src_reg &= ~link->src.mask; + ipu_cm_write(ipu, src_reg, link->src.reg); + } + + if (link->sink.mask) { + sink_reg = ipu_cm_read(ipu, link->sink.reg); + sink_reg &= ~link->sink.mask; + ipu_cm_write(ipu, sink_reg, link->sink.reg); + } + + spin_unlock_irqrestore(&ipu->lock, flags); + return 0; +} +EXPORT_SYMBOL_GPL(ipu_fsu_unlink); + +/* Link IDMAC channels in the FSU */ +int ipu_idmac_link(struct ipuv3_channel *src, struct ipuv3_channel *sink) +{ + return ipu_fsu_link(src->ipu, src->num, sink->num); +} +EXPORT_SYMBOL_GPL(ipu_idmac_link); + +/* Unlink IDMAC channels in the FSU */ +int ipu_idmac_unlink(struct ipuv3_channel *src, struct ipuv3_channel *sink) +{ + return ipu_fsu_unlink(src->ipu, src->num, sink->num); +} +EXPORT_SYMBOL_GPL(ipu_idmac_unlink); + struct ipu_devtype { const char *name; unsigned long cm_ofs; diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index fd47f8f..81baf53 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -75,6 +75,33 @@ struct ipu_soc; #define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * (n)) #define IPU_INT_STAT(n) IPU_CM_REG(0x0200 + 4 * (n)) +/* FS_PROC_FLOW1 */ +#define FS_PRPENC_ROT_SRC_SEL_MASK (0xf << 0) +#define FS_PRPENC_ROT_SRC_SEL_ENC (0x7 << 0) +#define FS_PRPVF_ROT_SRC_SEL_MASK (0xf << 8) +#define FS_PRPVF_ROT_SRC_SEL_VF (0x8 << 8) +#define FS_PP_SRC_SEL_MASK (0xf << 12) +#define FS_PP_ROT_SRC_SEL_MASK (0xf << 16) +#define FS_PP_ROT_SRC_SEL_PP (0x5 << 16) +#define FS_VDI1_SRC_SEL_MASK (0x3 << 20) +#define FS_VDI3_SRC_SEL_MASK (0x3 << 20) +#define FS_PRP_SRC_SEL_MASK (0xf << 24) +#define FS_VDI_SRC_SEL_MASK (0x3 << 28) +#define FS_VDI_SRC_SEL_CSI_DIRECT (0x1 << 28) +#define FS_VDI_SRC_SEL_VDOA (0x2 << 28) + +/* FS_PROC_FLOW2 */ +#define FS_PRP_ENC_DEST_SEL_MASK (0xf << 0) +#define FS_PRP_ENC_DEST_SEL_IRT_ENC (0x1 << 0) +#define FS_PRPVF_DEST_SEL_MASK (0xf << 4) +#define FS_PRPVF_DEST_SEL_IRT_VF (0x1 << 4) +#define FS_PRPVF_ROT_DEST_SEL_MASK (0xf << 8) +#define FS_PP_DEST_SEL_MASK (0xf << 12) +#define FS_PP_DEST_SEL_IRT_PP (0x3 << 12) +#define FS_PP_ROT_DEST_SEL_MASK (0xf << 16) +#define FS_PRPENC_ROT_DEST_SEL_MASK (0xf << 20) +#define FS_PRP_DEST_SEL_MASK (0xf << 24) + #define IPU_DI0_COUNTER_RELEASE (1 << 24) #define IPU_DI1_COUNTER_RELEASE (1 << 25) diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index c3de740..49d5439 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -97,6 +97,14 @@ enum ipu_channel_irq { #define IPUV3_CHANNEL_CSI2 2 #define IPUV3_CHANNEL_CSI3 3 #define IPUV3_CHANNEL_VDI_MEM_IC_VF 5 +/* + * NOTE: channels 6,7 are unused in the IPU and are not IDMAC channels, + * but the direct CSI->VDI linking is handled the same way as IDMAC + * channel linking in the FSU via the IPU_FS_PROC_FLOW registers, so + * these channel names are used to support the direct CSI->VDI link. + */ +#define IPUV3_CHANNEL_CSI_DIRECT 6 +#define IPUV3_CHANNEL_CSI_VDI_PREV 7 #define IPUV3_CHANNEL_MEM_VDI_PREV 8 #define IPUV3_CHANNEL_MEM_VDI_CUR 9 #define IPUV3_CHANNEL_MEM_VDI_NEXT 10 @@ -133,6 +141,7 @@ enum ipu_channel_irq { #define IPUV3_CHANNEL_ROT_PP_MEM 50 #define IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA 51 #define IPUV3_CHANNEL_MEM_BG_ASYNC_ALPHA 52 +#define IPUV3_NUM_CHANNELS 64 int ipu_map_irq(struct ipu_soc *ipu, int irq); int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, @@ -176,6 +185,10 @@ int ipu_idmac_get_current_buffer(struct ipuv3_channel *channel); bool ipu_idmac_buffer_is_ready(struct ipuv3_channel *channel, u32 buf_num); void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num); void ipu_idmac_clear_buffer(struct ipuv3_channel *channel, u32 buf_num); +int ipu_fsu_link(struct ipu_soc *ipu, int src_ch, int sink_ch); +int ipu_fsu_unlink(struct ipu_soc *ipu, int src_ch, int sink_ch); +int ipu_idmac_link(struct ipuv3_channel *src, struct ipuv3_channel *sink); +int ipu_idmac_unlink(struct ipuv3_channel *src, struct ipuv3_channel *sink); /* * IPU Channel Parameter Memory (cpmem) functions