diff mbox series

[U-Boot,2/6] dma: ti: k3-udma: Implement dma_get_cfg() interface

Message ID 20191118105910.14472-3-vigneshr@ti.com
State Superseded
Delegated to: Joe Hershberger
Headers show
Series J721e: Add networking support | expand

Commit Message

Raghavendra, Vignesh Nov. 18, 2019, 10:59 a.m. UTC
Implement dma_get_cfg() interface to pass flow id information for DMA
clients to use. This is needed because on K3 SoCs, CPSW (ethernet) and
UDMA (DMA provider) support "flows" within a given RX DMA channel. This
allows different network packets to be segregated while using same RX
DMA channel. In order for basic ethernet to work, CPSW slave must be
aware of the flow ID allocated for the RX channel by the DMA driver.
This interface allows CPSW to query flow ID from DMA provider and
configure it in CPSW HW.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/dma/ti/k3-udma.c       | 28 ++++++++++++++++++++++++++++
 include/linux/soc/ti/ti-udma.h | 19 +++++++++++++++++++
 2 files changed, 47 insertions(+)

Comments

Joe Hershberger Nov. 20, 2019, 10:53 p.m. UTC | #1
On Mon, Nov 18, 2019 at 4:59 AM Vignesh Raghavendra <vigneshr@ti.com> wrote:
>
> Implement dma_get_cfg() interface to pass flow id information for DMA
> clients to use. This is needed because on K3 SoCs, CPSW (ethernet) and
> UDMA (DMA provider) support "flows" within a given RX DMA channel. This
> allows different network packets to be segregated while using same RX
> DMA channel. In order for basic ethernet to work, CPSW slave must be
> aware of the flow ID allocated for the RX channel by the DMA driver.
> This interface allows CPSW to query flow ID from DMA provider and
> configure it in CPSW HW.
>
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>

Acked-by: Joe Hershberger <joe.hershberger@ni.com>
diff mbox series

Patch

diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 7336bad99412..3d24d8a7ff12 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -108,6 +108,8 @@  struct udma_chan {
 	struct udma_rchan *rchan;
 	struct udma_rflow *rflow;
 
+	struct ti_udma_drv_chan_cfg_data cfg_data;
+
 	u32 bcnt; /* number of bytes completed since the start of the channel */
 
 	bool pkt_mode; /* TR or packet */
@@ -1530,6 +1532,11 @@  static int udma_request(struct dma *dma)
 	uc->desc_rx_cur = 0;
 	uc->num_rx_bufs = 0;
 
+	if (uc->dir == DMA_DEV_TO_MEM) {
+		uc->cfg_data.flow_id_base = uc->rflow->id;
+		uc->cfg_data.flow_id_cnt = 1;
+	}
+
 	return 0;
 }
 
@@ -1804,6 +1811,26 @@  int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
 	return 0;
 }
 
+static int udma_get_cfg(struct dma *dma, u32 id, void **data)
+{
+	struct udma_dev *ud = dev_get_priv(dma->dev);
+	struct udma_chan *uc;
+
+	if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) {
+		dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id);
+		return -EINVAL;
+	}
+
+	switch (id) {
+	case TI_UDMA_CHAN_PRIV_INFO:
+		uc = &ud->channels[dma->id];
+		*data = &uc->cfg_data;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static const struct dma_ops udma_ops = {
 	.transfer	= udma_transfer,
 	.of_xlate	= udma_of_xlate,
@@ -1814,6 +1841,7 @@  static const struct dma_ops udma_ops = {
 	.send		= udma_send,
 	.receive	= udma_receive,
 	.prepare_rcv_buf = udma_prepare_rcv_buf,
+	.get_cfg	= udma_get_cfg,
 };
 
 static const struct udevice_id udma_ids[] = {
diff --git a/include/linux/soc/ti/ti-udma.h b/include/linux/soc/ti/ti-udma.h
index e9d4226c48d9..04e354fb2d69 100644
--- a/include/linux/soc/ti/ti-udma.h
+++ b/include/linux/soc/ti/ti-udma.h
@@ -21,4 +21,23 @@  struct ti_udma_drv_packet_data {
 	u32	dest_tag;
 };
 
+/**
+ * struct ti_udma_drv_chan_cfg_data - TI UDMA per channel specific
+ *                                     configuration data
+ *
+ * @flow_id_base: Start index of flow ID allocated to this channel
+ * @flow_id_cnt: Number of flows allocated for this channel starting at
+ *               flow_id_base
+ *
+ * TI UDMA channel specific data returned as part of dma_get_cfg() call
+ * from the DMA client driver.
+ */
+struct ti_udma_drv_chan_cfg_data {
+	u32	flow_id_base;
+	u32	flow_id_cnt;
+};
+
+/* TI UDMA specific flag IDs for dma_get_cfg() call */
+#define TI_UDMA_CHAN_PRIV_INFO		0
+
 #endif /* __TI_UDMA_H */