All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vignesh Raghavendra <vigneshr@ti.com>
To: u-boot@lists.denx.de
Subject: [PATCH 7/7] dma: ti: k3-udma: Add support for native configuration of chan/flow
Date: Mon, 10 May 2021 22:54:42 +0530	[thread overview]
Message-ID: <20210510172442.11146-8-vigneshr@ti.com> (raw)
In-Reply-To: <20210510172442.11146-1-vigneshr@ti.com>

In absence of Device Manager (DM) services such as at R5 SPL stage,
driver will have to natively setup TCHAN/RCHAN/RFLOW cfg registers.
Add support for the same.

Note that we still need to send chan/flow cfg message to TIFS via TISCI
client driver in order to open up firewalls around chan/flow but setting
up of cfg registers is handled locally.

U-Boot specific code is in a separate file included in main driver so
as to maintain similarity with kernel driver in order to ease porting of
code in future.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/dma/ti/k3-udma-u-boot.c | 177 ++++++++++++++++++++++++++++++++
 drivers/dma/ti/k3-udma.c        |  42 +++++++-
 2 files changed, 215 insertions(+), 4 deletions(-)
 create mode 100644 drivers/dma/ti/k3-udma-u-boot.c

diff --git a/drivers/dma/ti/k3-udma-u-boot.c b/drivers/dma/ti/k3-udma-u-boot.c
new file mode 100644
index 0000000000..3e04f551e2
--- /dev/null
+++ b/drivers/dma/ti/k3-udma-u-boot.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com
+ */
+
+#define UDMA_RCHAN_RFLOW_RNG_FLOWID_CNT_SHIFT	(16)
+
+/* How SRC/DST tag should be updated by UDMA in the descriptor's Word 3 */
+#define UDMA_RFLOW_SRCTAG_NONE		0
+#define UDMA_RFLOW_SRCTAG_CFG_TAG	1
+#define UDMA_RFLOW_SRCTAG_FLOW_ID	2
+#define UDMA_RFLOW_SRCTAG_SRC_TAG	4
+
+#define UDMA_RFLOW_DSTTAG_NONE		0
+#define UDMA_RFLOW_DSTTAG_CFG_TAG	1
+#define UDMA_RFLOW_DSTTAG_FLOW_ID	2
+#define UDMA_RFLOW_DSTTAG_DST_TAG_LO	4
+#define UDMA_RFLOW_DSTTAG_DST_TAG_HI	5
+
+#define UDMA_RFLOW_RFC_DEFAULT	\
+	((UDMA_RFLOW_SRCTAG_NONE <<  UDMA_RFLOW_RFC_SRC_TAG_HI_SEL_SHIFT) | \
+	 (UDMA_RFLOW_SRCTAG_SRC_TAG << UDMA_RFLOW_RFC_SRC_TAG_LO_SEL_SHIFT) | \
+	 (UDMA_RFLOW_DSTTAG_DST_TAG_HI << UDMA_RFLOW_RFC_DST_TAG_HI_SEL_SHIFT) | \
+	 (UDMA_RFLOW_DSTTAG_DST_TAG_LO << UDMA_RFLOW_RFC_DST_TAG_LO_SE_SHIFT))
+
+#define UDMA_RFLOW_RFx_REG_FDQ_SIZE_SHIFT	(16)
+
+/* TCHAN */
+static inline u32 udma_tchan_read(struct udma_tchan *tchan, int reg)
+{
+	if (!tchan)
+		return 0;
+	return udma_read(tchan->reg_chan, reg);
+}
+
+static inline void udma_tchan_write(struct udma_tchan *tchan, int reg, u32 val)
+{
+	if (!tchan)
+		return;
+	udma_write(tchan->reg_chan, reg, val);
+}
+
+static inline void udma_tchan_update_bits(struct udma_tchan *tchan, int reg,
+					  u32 mask, u32 val)
+{
+	if (!tchan)
+		return;
+	udma_update_bits(tchan->reg_chan, reg, mask, val);
+}
+
+/* RCHAN */
+static inline u32 udma_rchan_read(struct udma_rchan *rchan, int reg)
+{
+	if (!rchan)
+		return 0;
+	return udma_read(rchan->reg_chan, reg);
+}
+
+static inline void udma_rchan_write(struct udma_rchan *rchan, int reg, u32 val)
+{
+	if (!rchan)
+		return;
+	udma_write(rchan->reg_chan, reg, val);
+}
+
+static inline void udma_rchan_update_bits(struct udma_rchan *rchan, int reg,
+					  u32 mask, u32 val)
+{
+	if (!rchan)
+		return;
+	udma_update_bits(rchan->reg_chan, reg, mask, val);
+}
+
+/* RFLOW */
+static inline u32 udma_rflow_read(struct udma_rflow *rflow, int reg)
+{
+	if (!rflow)
+		return 0;
+	return udma_read(rflow->reg_rflow, reg);
+}
+
+static inline void udma_rflow_write(struct udma_rflow *rflow, int reg, u32 val)
+{
+	if (!rflow)
+		return;
+	udma_write(rflow->reg_rflow, reg, val);
+}
+
+static inline void udma_rflow_update_bits(struct udma_rflow *rflow, int reg,
+					  u32 mask, u32 val)
+{
+	if (!rflow)
+		return;
+	udma_update_bits(rflow->reg_rflow, reg, mask, val);
+}
+
+static void udma_alloc_tchan_raw(struct udma_chan *uc)
+{
+	u32 mode, fetch_size;
+
+	if (uc->config.pkt_mode)
+		mode = UDMA_CHAN_CFG_CHAN_TYPE_PACKET_PBRR;
+	else
+		mode = UDMA_CHAN_CFG_CHAN_TYPE_3RDP_BC_PBRR;
+
+	udma_tchan_update_bits(uc->tchan, UDMA_TCHAN_TCFG_REG,
+			       UDMA_CHAN_CFG_CHAN_TYPE_MASK, mode);
+
+	if (uc->config.dir == DMA_MEM_TO_MEM)
+		fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2;
+	else
+		fetch_size = cppi5_hdesc_calc_size(uc->config.needs_epib,
+						   uc->config.psd_size, 0) >> 2;
+
+	udma_tchan_update_bits(uc->tchan, UDMA_TCHAN_TCFG_REG,
+			       UDMA_CHAN_CFG_FETCH_SIZE_MASK, fetch_size);
+	udma_tchan_write(uc->tchan, UDMA_TCHAN_TCQ_REG,
+			 k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring));
+}
+
+static void udma_alloc_rchan_raw(struct udma_chan *uc)
+{
+	struct udma_dev *ud = uc->ud;
+	int fd_ring = k3_nav_ringacc_get_ring_id(uc->rflow->fd_ring);
+	int rx_ring = k3_nav_ringacc_get_ring_id(uc->rflow->r_ring);
+	int tc_ring = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring);
+	u32 rx_einfo_present = 0, rx_psinfo_present = 0;
+	u32 mode, fetch_size, rxcq_num;
+
+	if (uc->config.pkt_mode)
+		mode = UDMA_CHAN_CFG_CHAN_TYPE_PACKET_PBRR;
+	else
+		mode = UDMA_CHAN_CFG_CHAN_TYPE_3RDP_BC_PBRR;
+
+	udma_rchan_update_bits(uc->rchan, UDMA_RCHAN_RCFG_REG,
+			       UDMA_CHAN_CFG_CHAN_TYPE_MASK, mode);
+
+	if (uc->config.dir == DMA_MEM_TO_MEM) {
+		fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2;
+		rxcq_num = tc_ring;
+	} else {
+		fetch_size = cppi5_hdesc_calc_size(uc->config.needs_epib,
+						   uc->config.psd_size, 0) >> 2;
+		rxcq_num = rx_ring;
+	}
+
+	udma_rchan_update_bits(uc->rchan, UDMA_RCHAN_RCFG_REG,
+			       UDMA_CHAN_CFG_FETCH_SIZE_MASK, fetch_size);
+	udma_rchan_write(uc->rchan, UDMA_RCHAN_RCQ_REG, rxcq_num);
+
+	if (uc->config.dir == DMA_MEM_TO_MEM)
+		return;
+
+	if (ud->match_data->type == DMA_TYPE_UDMA &&
+	    uc->rflow->id != uc->rchan->id &&
+	    uc->config.dir != DMA_MEM_TO_MEM)
+		udma_rchan_write(uc->rchan, UDMA_RCHAN_RFLOW_RNG_REG, uc->rflow->id |
+				 1 << UDMA_RCHAN_RFLOW_RNG_FLOWID_CNT_SHIFT);
+
+	if (uc->config.needs_epib)
+		rx_einfo_present = UDMA_RFLOW_RFA_EINFO;
+
+	if (uc->config.psd_size)
+		rx_psinfo_present = UDMA_RFLOW_RFA_PSINFO;
+
+	udma_rflow_write(uc->rflow, UDMA_RFLOW_REG(A),
+			 rx_einfo_present | rx_psinfo_present | rxcq_num);
+
+	udma_rflow_write(uc->rflow, UDMA_RFLOW_REG(C), UDMA_RFLOW_RFC_DEFAULT);
+	udma_rflow_write(uc->rflow, UDMA_RFLOW_REG(D),
+			 fd_ring | fd_ring << UDMA_RFLOW_RFx_REG_FDQ_SIZE_SHIFT);
+	udma_rflow_write(uc->rflow, UDMA_RFLOW_REG(E),
+			 fd_ring | fd_ring << UDMA_RFLOW_RFx_REG_FDQ_SIZE_SHIFT);
+	udma_rflow_write(uc->rflow, UDMA_RFLOW_REG(G), fd_ring);
+	udma_rflow_write(uc->rflow, UDMA_RFLOW_REG(H),
+			 fd_ring | fd_ring << UDMA_RFLOW_RFx_REG_FDQ_SIZE_SHIFT);
+}
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 601868d7fc..411edef3a7 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -48,6 +48,9 @@ enum udma_mmr {
 	MMR_BCHANRT,
 	MMR_RCHANRT,
 	MMR_TCHANRT,
+	MMR_RCHAN,
+	MMR_TCHAN,
+	MMR_RFLOW,
 	MMR_LAST,
 };
 
@@ -56,9 +59,13 @@ static const char * const mmr_names[] = {
 	[MMR_BCHANRT] = "bchanrt",
 	[MMR_RCHANRT] = "rchanrt",
 	[MMR_TCHANRT] = "tchanrt",
+	[MMR_RCHAN] = "rchan",
+	[MMR_TCHAN] = "tchan",
+	[MMR_RFLOW] = "rflow",
 };
 
 struct udma_tchan {
+	void __iomem *reg_chan;
 	void __iomem *reg_rt;
 
 	int id;
@@ -71,12 +78,14 @@ struct udma_tchan {
 #define udma_bchan udma_tchan
 
 struct udma_rflow {
+	void __iomem *reg_rflow;
 	int id;
 	struct k3_nav_ring *fd_ring; /* Free Descriptor ring */
 	struct k3_nav_ring *r_ring; /* Receive ring */
 };
 
 struct udma_rchan {
+	void __iomem *reg_chan;
 	void __iomem *reg_rt;
 
 	int id;
@@ -335,6 +344,8 @@ static inline char *udma_get_dir_text(enum dma_direction dir)
 	return "invalid";
 }
 
+#include "k3-udma-u-boot.c"
+
 static void udma_reset_uchan(struct udma_chan *uc)
 {
 	memset(&uc->config, 0, sizeof(uc->config));
@@ -1014,10 +1025,20 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc)
 	req.txcq_qnum = tc_ring;
 
 	ret = tisci_rm->tisci_udmap_ops->tx_ch_cfg(tisci_rm->tisci, &req);
-	if (ret)
+	if (ret) {
 		dev_err(ud->dev, "tisci tx alloc failed %d\n", ret);
+		return ret;
+	}
 
-	return ret;
+	/*
+	 * Above TI SCI call handles firewall configuration, cfg
+	 * register configuration still has to be done locally in
+	 * absence of RM services.
+	 */
+	if (IS_ENABLED(CONFIG_K3_DM_FW))
+		udma_alloc_tchan_raw(uc);
+
+	return 0;
 }
 
 static int udma_alloc_rchan_sci_req(struct udma_chan *uc)
@@ -1114,11 +1135,21 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc)
 
 	ret = tisci_rm->tisci_udmap_ops->rx_flow_cfg(tisci_rm->tisci,
 						     &flow_req);
-	if (ret)
+	if (ret) {
 		dev_err(ud->dev, "tisci rx %u flow %u cfg failed %d\n",
 			uc->rchan->id, uc->rflow->id, ret);
+		return ret;
+	}
 
-	return ret;
+	/*
+	 * Above TI SCI call handles firewall configuration, cfg
+	 * register configuration still has to be done locally in
+	 * absence of RM services.
+	 */
+	if (IS_ENABLED(CONFIG_K3_DM_FW))
+		udma_alloc_rchan_raw(uc);
+
+	return 0;
 }
 
 static int udma_alloc_chan_resources(struct udma_chan *uc)
@@ -1751,6 +1782,7 @@ static int udma_probe(struct udevice *dev)
 		struct udma_tchan *tchan = &ud->tchans[i];
 
 		tchan->id = i;
+		tchan->reg_chan = ud->mmrs[MMR_TCHAN] + UDMA_CH_100(i);
 		tchan->reg_rt = ud->mmrs[MMR_TCHANRT] + UDMA_CH_1000(i);
 	}
 
@@ -1758,6 +1790,7 @@ static int udma_probe(struct udevice *dev)
 		struct udma_rchan *rchan = &ud->rchans[i];
 
 		rchan->id = i;
+		rchan->reg_chan = ud->mmrs[MMR_RCHAN] + UDMA_CH_100(i);
 		rchan->reg_rt = ud->mmrs[MMR_RCHANRT] + UDMA_CH_1000(i);
 	}
 
@@ -1765,6 +1798,7 @@ static int udma_probe(struct udevice *dev)
 		struct udma_rflow *rflow = &ud->rflows[i];
 
 		rflow->id = i;
+		rflow->reg_rflow = ud->mmrs[MMR_RFLOW] + UDMA_CH_40(i);
 	}
 
 	for (i = 0; i < ud->ch_count; i++) {
-- 
2.31.1

  parent reply	other threads:[~2021-05-10 17:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-10 17:24 [PATCH 0/7] J72xx: R5 SPL DMA support post HSM Rearch Vignesh Raghavendra
2021-05-10 17:24 ` [PATCH 1/7] mailbox: k3-sec-proxy: Add DM to DMSC communication thread Vignesh Raghavendra
2021-05-10 17:24 ` [PATCH 2/7] firmware: ti_sci: Implement GET_RANGE with static data Vignesh Raghavendra
2021-05-11  4:42   ` Lokesh Vutla
2021-05-11  5:54     ` Vignesh Raghavendra
2021-05-10 17:24 ` [PATCH 3/7] firmware: ti_sci: Add support for Resoure Management at R5 SPL stage Vignesh Raghavendra
2021-05-11  4:49   ` Lokesh Vutla
2021-05-11  6:20     ` Vignesh Raghavendra
2021-05-10 17:24 ` [PATCH 4/7] ARM: dts: j72xx-r5-common-proc-board: Add DM firmware node Vignesh Raghavendra
2021-05-10 17:24 ` [PATCH 5/7] ARM: dts: k3: Add cfg register space for ringacc and udmap Vignesh Raghavendra
2021-05-11  4:51   ` Lokesh Vutla
2021-05-11  6:04     ` Vignesh Raghavendra
2021-05-12  6:10       ` Lokesh Vutla
2021-05-12  6:20         ` Vignesh Raghavendra
2021-05-12  6:39           ` Lokesh Vutla
2021-05-10 17:24 ` [PATCH 6/7] soc: ti: k3-navss-ringacc: Add support for native configuration of rings Vignesh Raghavendra
2021-05-10 17:24 ` Vignesh Raghavendra [this message]
2021-05-11 16:22 ` [PATCH 0/7] J72xx: R5 SPL DMA support post HSM Rearch Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210510172442.11146-8-vigneshr@ti.com \
    --to=vigneshr@ti.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.