Browse Source

dmaengine: ti: k3-udma: Add support for j721e

The changes needed to support the UDMAP/PDMA on J721e:
- We have 3 performance levels for channels compared to 2 in am6
- The output event offset (oes) is changed in sysfw for rchans
- PDMA's staticTR Z is now larger
- PDMA have new fields: acc32 and burst.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Peter Ujfalusi 6 years ago
parent
commit
18563bd252
3 changed files with 102 additions and 13 deletions
  1. 88 9
      drivers/dma/ti/k3-udma.c
  2. 5 4
      drivers/dma/ti/k3-udma.h
  3. 9 0
      include/dt-bindings/dma/k3-udma.h

+ 88 - 9
drivers/dma/ti/k3-udma.c

@@ -77,6 +77,11 @@ struct udma_rflow {
 
 struct udma_match_data {
 	bool enable_memcpy_support;
+	bool have_acc32;
+	bool have_burst;
+	u32 statictr_z_mask;
+	u32 rchan_oes_offset;
+
 	u8 tpl_levels;
 	u32 level_start_idx[];
 };
@@ -193,6 +198,8 @@ struct udma_chan {
 	u32 src_thread;
 	u32 dst_thread;
 	u32 static_tr_type;
+	bool enable_acc32;
+	bool enable_burst;
 	enum udma_tp_level channel_tpl; /* Channel Throughput Level */
 
 	/* dmapool for packet mode descriptors */
@@ -706,6 +713,8 @@ static inline int udma_reset_chan(struct udma_chan *uc, bool hard)
 		uc->remote_thread_id = uc_backup.remote_thread_id;
 		uc->pkt_mode = uc_backup.pkt_mode;
 		uc->static_tr_type = uc_backup.static_tr_type;
+		uc->enable_acc32 = uc_backup.enable_acc32;
+		uc->enable_burst = uc_backup.enable_burst;
 		uc->channel_tpl = uc_backup.channel_tpl;
 		uc->psd_size = uc_backup.psd_size;
 		uc->metadata_size = uc_backup.metadata_size;
@@ -748,6 +757,7 @@ static inline bool udma_chan_needs_reconfiguration(struct udma_chan *uc)
 
 static int udma_start(struct udma_chan *uc)
 {
+	const struct udma_match_data *match_data = uc->ud->match_data;
 	struct virt_dma_desc *vd = vchan_next_desc(&uc->vc);
 
 	if (!vd) {
@@ -775,13 +785,21 @@ static int udma_start(struct udma_chan *uc)
 	case DMA_DEV_TO_MEM:
 		/* Config remote TR */
 		if (uc->static_tr_type) {
+			u32 val = PDMA_STATIC_TR_Y(uc->desc->static_tr.elcnt) |
+				  PDMA_STATIC_TR_X(uc->desc->static_tr.elsize);
+
+			if (uc->enable_acc32 && match_data->have_acc32)
+				val |= PDMA_STATIC_TR_XY_ACC32;
+			if (uc->enable_burst && match_data->have_burst)
+				val |= PDMA_STATIC_TR_XY_BURST;
+
 			udma_rchanrt_write(uc->rchan,
-				UDMA_RCHAN_RT_PEER_STATIC_TR_XY_REG,
-				PDMA_STATIC_TR_Y(uc->desc->static_tr.elcnt) |
-				PDMA_STATIC_TR_X(uc->desc->static_tr.elsize));
+				UDMA_RCHAN_RT_PEER_STATIC_TR_XY_REG, val);
+
 			udma_rchanrt_write(uc->rchan,
 				UDMA_RCHAN_RT_PEER_STATIC_TR_Z_REG,
-				PDMA_STATIC_TR_Z(uc->desc->static_tr.bstcnt));
+				PDMA_STATIC_TR_Z(uc->desc->static_tr.bstcnt,
+						 match_data->statictr_z_mask));
 
 			/* save the current staticTR configuration */
 			memcpy(&uc->static_tr, &uc->desc->static_tr,
@@ -799,10 +817,16 @@ static int udma_start(struct udma_chan *uc)
 	case DMA_MEM_TO_DEV:
 		/* Config remote TR */
 		if (uc->static_tr_type) {
+			u32 val = PDMA_STATIC_TR_Y(uc->desc->static_tr.elcnt) |
+				  PDMA_STATIC_TR_X(uc->desc->static_tr.elsize);
+
+			if (uc->enable_acc32 && match_data->have_acc32)
+				val |= PDMA_STATIC_TR_XY_ACC32;
+			if (uc->enable_burst && match_data->have_burst)
+				val |= PDMA_STATIC_TR_XY_BURST;
+
 			udma_tchanrt_write(uc->tchan,
-				UDMA_TCHAN_RT_PEER_STATIC_TR_XY_REG,
-				PDMA_STATIC_TR_Y(uc->desc->static_tr.elcnt) |
-				PDMA_STATIC_TR_X(uc->desc->static_tr.elsize));
+				UDMA_TCHAN_RT_PEER_STATIC_TR_XY_REG, val);
 
 			/* save the current staticTR configuration */
 			memcpy(&uc->static_tr, &uc->desc->static_tr,
@@ -1430,6 +1454,7 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
 	struct udma_dev *ud = to_udma_dev(chan->device);
 	struct udma_tisci_rm *tisci_rm = &ud->tisci_rm;
 	const struct ti_sci_rm_udmap_ops *tisci_ops = tisci_rm->tisci_udmap_ops;
+	const struct udma_match_data *match_data = uc->ud->match_data;
 	struct udma_tchan *tchan;
 	struct udma_rchan *rchan;
 	int ret;
@@ -1722,7 +1747,8 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
 			uc->irq_ra_tisci = k3_ringacc_get_tisci_dev_id(
 								rchan->r_ring);
 			uc->irq_ra_idx = rx_ring;
-			uc->irq_udma_idx = 0x2000 + rchan->id;
+			uc->irq_udma_idx = match_data->rchan_oes_offset +
+					   rchan->id;
 		}
 	}
 
@@ -1823,6 +1849,8 @@ err_res_free:
 	uc->dir = DMA_MEM_TO_MEM;
 	uc->pkt_mode = false;
 	uc->static_tr_type = 0;
+	uc->enable_acc32 = 0;
+	uc->enable_burst = 0;
 	uc->channel_tpl = 0;
 	uc->psd_size = 0;
 	uc->metadata_size = 0;
@@ -2019,7 +2047,8 @@ static inline int udma_configure_statictr(struct udma_chan *uc,
 		else
 			d->static_tr.bstcnt = d->residue / div;
 
-		if (uc->dir == DMA_DEV_TO_MEM && d->static_tr.bstcnt > 0xfff)
+		if (uc->dir == DMA_DEV_TO_MEM &&
+		    d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask)
 			return -EINVAL;
 	} else {
 		d->static_tr.bstcnt = 0;
@@ -2871,6 +2900,8 @@ static void udma_free_chan_resources(struct dma_chan *chan)
 	uc->dir = DMA_MEM_TO_MEM;
 	uc->pkt_mode = false;
 	uc->static_tr_type = 0;
+	uc->enable_acc32 = 0;
+	uc->enable_burst = 0;
 	uc->channel_tpl = 0;
 	uc->psd_size = 0;
 	uc->metadata_size = 0;
@@ -2931,6 +2962,13 @@ static bool udma_dma_filter_fn(struct dma_chan *chan, void *param)
 	if (!of_property_read_u32(chconf_node, "statictr-type", &val))
 		uc->static_tr_type = val;
 
+	if (uc->static_tr_type == PSIL_STATIC_TR_XY) {
+		uc->enable_acc32 = of_property_read_bool(chconf_node,
+							 "enable-acc32");
+		uc->enable_burst = of_property_read_bool(chconf_node,
+							 "enable-burst");
+	}
+
 	if (!of_property_read_u32(chconf_node, "ti,channel-tpl", &val))
 		uc->channel_tpl = val;
 
@@ -2983,6 +3021,10 @@ static struct dma_chan *udma_of_xlate(struct of_phandle_args *dma_spec,
 
 static struct udma_match_data am654_main_data = {
 	.enable_memcpy_support = true,
+	.have_acc32 = false,
+	.have_burst = false,
+	.statictr_z_mask = GENMASK(11, 0),
+	.rchan_oes_offset = 0x2000,
 	.tpl_levels = 2,
 	.level_start_idx = {
 		[0] = 8, /* Normal channels */
@@ -2992,6 +3034,37 @@ static struct udma_match_data am654_main_data = {
 
 static struct udma_match_data am654_mcu_data = {
 	.enable_memcpy_support = false, /* MEM_TO_MEM is slow via MCU UDMA */
+	.have_acc32 = false,
+	.have_burst = false,
+	.statictr_z_mask = GENMASK(11, 0),
+	.rchan_oes_offset = 0x2000,
+	.tpl_levels = 2,
+	.level_start_idx = {
+		[0] = 2, /* Normal channels */
+		[1] = 0, /* High Throughput channels */
+	},
+};
+
+static struct udma_match_data j721e_main_data = {
+	.enable_memcpy_support = true,
+	.have_acc32 = true,
+	.have_burst = true,
+	.statictr_z_mask = GENMASK(23, 0),
+	.rchan_oes_offset = 0x400,
+	.tpl_levels = 3,
+	.level_start_idx = {
+		[0] = 16, /* Normal channels */
+		[1] = 4, /* High Throughput channels */
+		[2] = 0, /* Ultra High Throughput channels */
+	},
+};
+
+static struct udma_match_data j721e_mcu_data = {
+	.enable_memcpy_support = false, /* MEM_TO_MEM is slow via MCU UDMA */
+	.have_acc32 = true,
+	.have_burst = true,
+	.statictr_z_mask = GENMASK(23, 0),
+	.rchan_oes_offset = 0x400,
 	.tpl_levels = 2,
 	.level_start_idx = {
 		[0] = 2, /* Normal channels */
@@ -3006,6 +3079,12 @@ static const struct of_device_id udma_of_match[] = {
 	}, {
 		.compatible = "ti,am654-navss-mcu-udmap",
 		.data = &am654_mcu_data,
+	}, {
+		.compatible = "ti,j721e-navss-main-udmap",
+		.data = &j721e_main_data,
+	}, {
+		.compatible = "ti,j721e-navss-mcu-udmap",
+		.data = &j721e_mcu_data,
 	},
 	{},
 };

+ 5 - 4
drivers/dma/ti/k3-udma.h

@@ -84,14 +84,14 @@
 #define PDMA_STATIC_TR_X(x)	\
 	(((x) << PDMA_STATIC_TR_X_SHIFT) & PDMA_STATIC_TR_X_MASK)
 
+#define PDMA_STATIC_TR_XY_ACC32		BIT(30)
+#define PDMA_STATIC_TR_XY_BURST		BIT(31)
+
 /*
  * UDMA_TCHAN_RT_PEER_STATIC_TR_Z_REG /
  * UDMA_RCHAN_RT_PEER_STATIC_TR_Z_REG
  */
-#define PDMA_STATIC_TR_Z_MASK		GENMASK(11, 0)
-#define PDMA_STATIC_TR_Z_SHIFT		(0)
-#define PDMA_STATIC_TR_Z(x)	\
-	(((x) << PDMA_STATIC_TR_Z_SHIFT) & PDMA_STATIC_TR_Z_MASK)
+#define PDMA_STATIC_TR_Z(x, mask)	((x) & (mask))
 
 /* Private API to UDMA via k3-udma-private */
 #include <linux/of.h>
@@ -114,6 +114,7 @@ enum udma_rm_range {
 enum udma_tp_level {
 	UDMA_TP_NORMAL = 0,
 	UDMA_TP_HIGH = 1,
+	UDMA_TP_ULTRAHIGH = 2,
 	UDMA_TP_LAST,
 };
 

+ 9 - 0
include/dt-bindings/dma/k3-udma.h

@@ -17,6 +17,15 @@
 		statictr-type = <PSIL_STATIC_TR_XY>;	\
 	}
 
+/* j721e have support for ACC32 and burst flags for McASP */
+#define UDMA_PDMA_J721E_MCASP(id)			\
+	ti,psil-config##id {				\
+		linux,udma-mode = <UDMA_TR_MODE>;	\
+		statictr-type = <PSIL_STATIC_TR_XY>;	\
+		enable-acc32;				\
+		enable-burst;				\
+	}
+
 #define UDMA_PDMA_PKT_XY(id)				\
 	ti,psil-config##id {				\
 		linux,udma-mode = <UDMA_PKT_MODE>;	\