dma: ti: k3-udma: Introduce udma_chan_config struct
Encapsulate channel configuration in a separate struct so as to ease resetting of these fields with memset() and also to increase readability of the code. Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
This commit is contained in:
		
							parent
							
								
									b3f95997ce
								
							
						
					
					
						commit
						af374c24d9
					
				|  | @ -137,6 +137,26 @@ struct udma_dev { | |||
| 	u32 ch_count; | ||||
| }; | ||||
| 
 | ||||
| struct udma_chan_config { | ||||
| 	u32 psd_size; /* size of Protocol Specific Data */ | ||||
| 	u32 metadata_size; /* (needs_epib ? 16:0) + psd_size */ | ||||
| 	u32 hdesc_size; /* Size of a packet descriptor in packet mode */ | ||||
| 	int remote_thread_id; | ||||
| 	u32 atype; | ||||
| 	u32 src_thread; | ||||
| 	u32 dst_thread; | ||||
| 	enum psil_endpoint_type ep_type; | ||||
| 	enum udma_tp_level channel_tpl; /* Channel Throughput Level */ | ||||
| 
 | ||||
| 	enum dma_direction dir; | ||||
| 
 | ||||
| 	unsigned int pkt_mode:1; /* TR or packet */ | ||||
| 	unsigned int needs_epib:1; /* EPIB is needed for the communication or not */ | ||||
| 	unsigned int enable_acc32:1; | ||||
| 	unsigned int enable_burst:1; | ||||
| 	unsigned int notdpkt:1; /* Suppress sending TDC packet */ | ||||
| }; | ||||
| 
 | ||||
| struct udma_chan { | ||||
| 	struct udma_dev *ud; | ||||
| 	char name[20]; | ||||
|  | @ -149,20 +169,11 @@ struct udma_chan { | |||
| 
 | ||||
| 	u32 bcnt; /* number of bytes completed since the start of the channel */ | ||||
| 
 | ||||
| 	bool pkt_mode; /* TR or packet */ | ||||
| 	bool needs_epib; /* EPIB is needed for the communication or not */ | ||||
| 	u32 psd_size; /* size of Protocol Specific Data */ | ||||
| 	u32 metadata_size; /* (needs_epib ? 16:0) + psd_size */ | ||||
| 	int slave_thread_id; | ||||
| 	u32 src_thread; | ||||
| 	u32 dst_thread; | ||||
| 	u32 static_tr_type; | ||||
| 	struct udma_chan_config config; | ||||
| 
 | ||||
| 	u32 id; | ||||
| 	enum dma_direction dir; | ||||
| 
 | ||||
| 	struct cppi5_host_desc_t *desc_tx; | ||||
| 	u32 hdesc_size; | ||||
| 	bool in_use; | ||||
| 	void	*desc_rx; | ||||
| 	u32	num_rx_bufs; | ||||
|  | @ -288,7 +299,7 @@ static inline bool udma_is_chan_running(struct udma_chan *uc) | |||
| 	u32 trt_ctl = 0; | ||||
| 	u32 rrt_ctl = 0; | ||||
| 
 | ||||
| 	switch (uc->dir) { | ||||
| 	switch (uc->config.dir) { | ||||
| 	case DMA_DEV_TO_MEM: | ||||
| 		rrt_ctl = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_CTL_REG); | ||||
| 		pr_debug("%s: rrt_ctl: 0x%08x (peer: 0x%08x)\n", | ||||
|  | @ -322,7 +333,7 @@ static int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr) | |||
| 	struct k3_nav_ring *ring = NULL; | ||||
| 	int ret = -ENOENT; | ||||
| 
 | ||||
| 	switch (uc->dir) { | ||||
| 	switch (uc->config.dir) { | ||||
| 	case DMA_DEV_TO_MEM: | ||||
| 		ring = uc->rchan->r_ring; | ||||
| 		break; | ||||
|  | @ -347,7 +358,7 @@ static void udma_reset_rings(struct udma_chan *uc) | |||
| 	struct k3_nav_ring *ring1 = NULL; | ||||
| 	struct k3_nav_ring *ring2 = NULL; | ||||
| 
 | ||||
| 	switch (uc->dir) { | ||||
| 	switch (uc->config.dir) { | ||||
| 	case DMA_DEV_TO_MEM: | ||||
| 		ring1 = uc->rchan->fd_ring; | ||||
| 		ring2 = uc->rchan->r_ring; | ||||
|  | @ -409,7 +420,7 @@ static inline int udma_stop_hard(struct udma_chan *uc) | |||
| { | ||||
| 	pr_debug("%s: ENTER (chan%d)\n", __func__, uc->id); | ||||
| 
 | ||||
| 	switch (uc->dir) { | ||||
| 	switch (uc->config.dir) { | ||||
| 	case DMA_DEV_TO_MEM: | ||||
| 		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_RT_EN_REG, 0); | ||||
| 		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_CTL_REG, 0); | ||||
|  | @ -435,9 +446,8 @@ static int udma_start(struct udma_chan *uc) | |||
| 	if (udma_is_chan_running(uc)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	pr_debug("%s: chan:%d dir:%s (static_tr_type: %d)\n", | ||||
| 		 __func__, uc->id, udma_get_dir_text(uc->dir), | ||||
| 		 uc->static_tr_type); | ||||
| 	pr_debug("%s: chan:%d dir:%s\n", | ||||
| 		 __func__, uc->id, udma_get_dir_text(uc->config.dir)); | ||||
| 
 | ||||
| 	/* Make sure that we clear the teardown bit, if it is set */ | ||||
| 	udma_stop_hard(uc); | ||||
|  | @ -445,7 +455,7 @@ static int udma_start(struct udma_chan *uc) | |||
| 	/* Reset all counters */ | ||||
| 	udma_reset_counters(uc); | ||||
| 
 | ||||
| 	switch (uc->dir) { | ||||
| 	switch (uc->config.dir) { | ||||
| 	case DMA_DEV_TO_MEM: | ||||
| 		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_CTL_REG, | ||||
| 				   UDMA_CHAN_RT_CTL_EN); | ||||
|  | @ -547,10 +557,10 @@ static inline void udma_stop_dev2mem(struct udma_chan *uc, bool sync) | |||
| static inline int udma_stop(struct udma_chan *uc) | ||||
| { | ||||
| 	pr_debug("%s: chan:%d dir:%s\n", | ||||
| 		 __func__, uc->id, udma_get_dir_text(uc->dir)); | ||||
| 		 __func__, uc->id, udma_get_dir_text(uc->config.dir)); | ||||
| 
 | ||||
| 	udma_reset_counters(uc); | ||||
| 	switch (uc->dir) { | ||||
| 	switch (uc->config.dir) { | ||||
| 	case DMA_DEV_TO_MEM: | ||||
| 		udma_stop_dev2mem(uc, true); | ||||
| 		break; | ||||
|  | @ -851,7 +861,7 @@ static int udma_alloc_rx_resources(struct udma_chan *uc) | |||
| 		return ret; | ||||
| 
 | ||||
| 	/* For MEM_TO_MEM we don't need rflow or rings */ | ||||
| 	if (uc->dir == DMA_MEM_TO_MEM) | ||||
| 	if (uc->config.dir == DMA_MEM_TO_MEM) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	ret = udma_get_rflow(uc, uc->rchan->id); | ||||
|  | @ -913,7 +923,7 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc) | |||
| 	u32 mode; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (uc->pkt_mode) | ||||
| 	if (uc->config.pkt_mode) | ||||
| 		mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR; | ||||
| 	else | ||||
| 		mode = TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBRR; | ||||
|  | @ -924,11 +934,11 @@ static int udma_alloc_tchan_sci_req(struct udma_chan *uc) | |||
| 	req.nav_id = tisci_rm->tisci_dev_id; | ||||
| 	req.index = uc->tchan->id; | ||||
| 	req.tx_chan_type = mode; | ||||
| 	if (uc->dir == DMA_MEM_TO_MEM) | ||||
| 	if (uc->config.dir == DMA_MEM_TO_MEM) | ||||
| 		req.tx_fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2; | ||||
| 	else | ||||
| 		req.tx_fetch_size = cppi5_hdesc_calc_size(uc->needs_epib, | ||||
| 							  uc->psd_size, | ||||
| 		req.tx_fetch_size = cppi5_hdesc_calc_size(uc->config.needs_epib, | ||||
| 							  uc->config.psd_size, | ||||
| 							  0) >> 2; | ||||
| 	req.txcq_qnum = tc_ring; | ||||
| 
 | ||||
|  | @ -951,7 +961,7 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) | |||
| 	u32 mode; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (uc->pkt_mode) | ||||
| 	if (uc->config.pkt_mode) | ||||
| 		mode = TI_SCI_RM_UDMAP_CHAN_TYPE_PKT_PBRR; | ||||
| 	else | ||||
| 		mode = TI_SCI_RM_UDMAP_CHAN_TYPE_3RDP_BCOPY_PBRR; | ||||
|  | @ -964,16 +974,16 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) | |||
| 	req.nav_id = tisci_rm->tisci_dev_id; | ||||
| 	req.index = uc->rchan->id; | ||||
| 	req.rx_chan_type = mode; | ||||
| 	if (uc->dir == DMA_MEM_TO_MEM) { | ||||
| 	if (uc->config.dir == DMA_MEM_TO_MEM) { | ||||
| 		req.rx_fetch_size = sizeof(struct cppi5_desc_hdr_t) >> 2; | ||||
| 		req.rxcq_qnum = tc_ring; | ||||
| 	} else { | ||||
| 		req.rx_fetch_size = cppi5_hdesc_calc_size(uc->needs_epib, | ||||
| 							  uc->psd_size, | ||||
| 		req.rx_fetch_size = cppi5_hdesc_calc_size(uc->config.needs_epib, | ||||
| 							  uc->config.psd_size, | ||||
| 							  0) >> 2; | ||||
| 		req.rxcq_qnum = rx_ring; | ||||
| 	} | ||||
| 	if (uc->rflow->id != uc->rchan->id && uc->dir != DMA_MEM_TO_MEM) { | ||||
| 	if (uc->rflow->id != uc->rchan->id && uc->config.dir != DMA_MEM_TO_MEM) { | ||||
| 		req.flowid_start = uc->rflow->id; | ||||
| 		req.flowid_cnt = 1; | ||||
| 	} | ||||
|  | @ -984,7 +994,7 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) | |||
| 			uc->rchan->id, ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	if (uc->dir == DMA_MEM_TO_MEM) | ||||
| 	if (uc->config.dir == DMA_MEM_TO_MEM) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	flow_req.valid_params = | ||||
|  | @ -1006,12 +1016,12 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc) | |||
| 	flow_req.nav_id = tisci_rm->tisci_dev_id; | ||||
| 	flow_req.flow_index = uc->rflow->id; | ||||
| 
 | ||||
| 	if (uc->needs_epib) | ||||
| 	if (uc->config.needs_epib) | ||||
| 		flow_req.rx_einfo_present = 1; | ||||
| 	else | ||||
| 		flow_req.rx_einfo_present = 0; | ||||
| 
 | ||||
| 	if (uc->psd_size) | ||||
| 	if (uc->config.psd_size) | ||||
| 		flow_req.rx_psinfo_present = 1; | ||||
| 	else | ||||
| 		flow_req.rx_psinfo_present = 0; | ||||
|  | @ -1044,11 +1054,12 @@ static int udma_alloc_chan_resources(struct udma_chan *uc) | |||
| 	int ret; | ||||
| 
 | ||||
| 	pr_debug("%s: chan:%d as %s\n", | ||||
| 		 __func__, uc->id, udma_get_dir_text(uc->dir)); | ||||
| 		 __func__, uc->id, udma_get_dir_text(uc->config.dir)); | ||||
| 
 | ||||
| 	switch (uc->dir) { | ||||
| 	switch (uc->config.dir) { | ||||
| 	case DMA_MEM_TO_MEM: | ||||
| 		/* Non synchronized - mem to mem type of transfer */ | ||||
| 		uc->config.pkt_mode = false; | ||||
| 		ret = udma_get_chan_pair(uc); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
|  | @ -1061,8 +1072,8 @@ static int udma_alloc_chan_resources(struct udma_chan *uc) | |||
| 		if (ret) | ||||
| 			goto err_free_res; | ||||
| 
 | ||||
| 		uc->src_thread = ud->psil_base + uc->tchan->id; | ||||
| 		uc->dst_thread = (ud->psil_base + uc->rchan->id) | 0x8000; | ||||
| 		uc->config.src_thread = ud->psil_base + uc->tchan->id; | ||||
| 		uc->config.dst_thread = (ud->psil_base + uc->rchan->id) | 0x8000; | ||||
| 		break; | ||||
| 	case DMA_MEM_TO_DEV: | ||||
| 		/* Slave transfer synchronized - mem to dev (TX) trasnfer */ | ||||
|  | @ -1070,10 +1081,9 @@ static int udma_alloc_chan_resources(struct udma_chan *uc) | |||
| 		if (ret) | ||||
| 			goto err_free_res; | ||||
| 
 | ||||
| 		uc->src_thread = ud->psil_base + uc->tchan->id; | ||||
| 		uc->dst_thread = uc->slave_thread_id; | ||||
| 		if (!(uc->dst_thread & 0x8000)) | ||||
| 			uc->dst_thread |= 0x8000; | ||||
| 		uc->config.src_thread = ud->psil_base + uc->tchan->id; | ||||
| 		uc->config.dst_thread = uc->config.remote_thread_id; | ||||
| 		uc->config.dst_thread |= 0x8000; | ||||
| 
 | ||||
| 		break; | ||||
| 	case DMA_DEV_TO_MEM: | ||||
|  | @ -1082,19 +1092,19 @@ static int udma_alloc_chan_resources(struct udma_chan *uc) | |||
| 		if (ret) | ||||
| 			goto err_free_res; | ||||
| 
 | ||||
| 		uc->src_thread = uc->slave_thread_id; | ||||
| 		uc->dst_thread = (ud->psil_base + uc->rchan->id) | 0x8000; | ||||
| 		uc->config.src_thread = uc->config.remote_thread_id; | ||||
| 		uc->config.dst_thread = (ud->psil_base + uc->rchan->id) | 0x8000; | ||||
| 
 | ||||
| 		break; | ||||
| 	default: | ||||
| 		/* Can not happen */ | ||||
| 		pr_debug("%s: chan:%d invalid direction (%u)\n", | ||||
| 			 __func__, uc->id, uc->dir); | ||||
| 			 __func__, uc->id, uc->config.dir); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	/* We have channel indexes and rings */ | ||||
| 	if (uc->dir == DMA_MEM_TO_MEM) { | ||||
| 	if (uc->config.dir == DMA_MEM_TO_MEM) { | ||||
| 		ret = udma_alloc_tchan_sci_req(uc); | ||||
| 		if (ret) | ||||
| 			goto err_free_res; | ||||
|  | @ -1104,7 +1114,7 @@ static int udma_alloc_chan_resources(struct udma_chan *uc) | |||
| 			goto err_free_res; | ||||
| 	} else { | ||||
| 		/* Slave transfer */ | ||||
| 		if (uc->dir == DMA_MEM_TO_DEV) { | ||||
| 		if (uc->config.dir == DMA_MEM_TO_DEV) { | ||||
| 			ret = udma_alloc_tchan_sci_req(uc); | ||||
| 			if (ret) | ||||
| 				goto err_free_res; | ||||
|  | @ -1125,7 +1135,7 @@ static int udma_alloc_chan_resources(struct udma_chan *uc) | |||
| 	} | ||||
| 
 | ||||
| 	/* PSI-L pairing */ | ||||
| 	ret = udma_navss_psil_pair(ud, uc->src_thread, uc->dst_thread); | ||||
| 	ret = udma_navss_psil_pair(ud, uc->config.src_thread, uc->config.dst_thread); | ||||
| 	if (ret) { | ||||
| 		dev_err(ud->dev, "k3_nav_psil_request_link fail\n"); | ||||
| 		goto err_free_res; | ||||
|  | @ -1136,7 +1146,7 @@ static int udma_alloc_chan_resources(struct udma_chan *uc) | |||
| err_free_res: | ||||
| 	udma_free_tx_resources(uc); | ||||
| 	udma_free_rx_resources(uc); | ||||
| 	uc->slave_thread_id = -1; | ||||
| 	uc->config.remote_thread_id = -1; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  | @ -1145,15 +1155,15 @@ static void udma_free_chan_resources(struct udma_chan *uc) | |||
| 	/* Some configuration to UDMA-P channel: disable, reset, whatever */ | ||||
| 
 | ||||
| 	/* Release PSI-L pairing */ | ||||
| 	udma_navss_psil_unpair(uc->ud, uc->src_thread, uc->dst_thread); | ||||
| 	udma_navss_psil_unpair(uc->ud, uc->config.src_thread, uc->config.dst_thread); | ||||
| 
 | ||||
| 	/* Reset the rings for a new start */ | ||||
| 	udma_reset_rings(uc); | ||||
| 	udma_free_tx_resources(uc); | ||||
| 	udma_free_rx_resources(uc); | ||||
| 
 | ||||
| 	uc->slave_thread_id = -1; | ||||
| 	uc->dir = DMA_MEM_TO_MEM; | ||||
| 	uc->config.remote_thread_id = -1; | ||||
| 	uc->config.dir = DMA_MEM_TO_MEM; | ||||
| } | ||||
| 
 | ||||
| static int udma_get_mmrs(struct udevice *dev) | ||||
|  | @ -1377,10 +1387,10 @@ static int udma_probe(struct udevice *dev) | |||
| 
 | ||||
| 		uc->ud = ud; | ||||
| 		uc->id = i; | ||||
| 		uc->slave_thread_id = -1; | ||||
| 		uc->config.remote_thread_id = -1; | ||||
| 		uc->tchan = NULL; | ||||
| 		uc->rchan = NULL; | ||||
| 		uc->dir = DMA_MEM_TO_MEM; | ||||
| 		uc->config.dir = DMA_MEM_TO_MEM; | ||||
| 		sprintf(uc->name, "UDMA chan%d\n", i); | ||||
| 		if (!i) | ||||
| 			uc->in_use = true; | ||||
|  | @ -1527,6 +1537,7 @@ static int udma_transfer(struct udevice *dev, int direction, | |||
| static int udma_request(struct dma *dma) | ||||
| { | ||||
| 	struct udma_dev *ud = dev_get_priv(dma->dev); | ||||
| 	struct udma_chan_config *ucc; | ||||
| 	struct udma_chan *uc; | ||||
| 	unsigned long dummy; | ||||
| 	int ret; | ||||
|  | @ -1537,30 +1548,27 @@ static int udma_request(struct dma *dma) | |||
| 	} | ||||
| 
 | ||||
| 	uc = &ud->channels[dma->id]; | ||||
| 	ucc = &uc->config; | ||||
| 	ret = udma_alloc_chan_resources(uc); | ||||
| 	if (ret) { | ||||
| 		dev_err(dma->dev, "alloc dma res failed %d\n", ret); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	uc->hdesc_size = cppi5_hdesc_calc_size(uc->needs_epib, | ||||
| 					       uc->psd_size, 0); | ||||
| 	uc->hdesc_size = ALIGN(uc->hdesc_size, ARCH_DMA_MINALIGN); | ||||
| 
 | ||||
| 	if (uc->dir == DMA_MEM_TO_DEV) { | ||||
| 		uc->desc_tx = dma_alloc_coherent(uc->hdesc_size, &dummy); | ||||
| 		memset(uc->desc_tx, 0, uc->hdesc_size); | ||||
| 	if (uc->config.dir == DMA_MEM_TO_DEV) { | ||||
| 		uc->desc_tx = dma_alloc_coherent(ucc->hdesc_size, &dummy); | ||||
| 		memset(uc->desc_tx, 0, ucc->hdesc_size); | ||||
| 	} else { | ||||
| 		uc->desc_rx = dma_alloc_coherent( | ||||
| 				uc->hdesc_size * UDMA_RX_DESC_NUM, &dummy); | ||||
| 		memset(uc->desc_rx, 0, uc->hdesc_size * UDMA_RX_DESC_NUM); | ||||
| 				ucc->hdesc_size * UDMA_RX_DESC_NUM, &dummy); | ||||
| 		memset(uc->desc_rx, 0, ucc->hdesc_size * UDMA_RX_DESC_NUM); | ||||
| 	} | ||||
| 
 | ||||
| 	uc->in_use = true; | ||||
| 	uc->desc_rx_cur = 0; | ||||
| 	uc->num_rx_bufs = 0; | ||||
| 
 | ||||
| 	if (uc->dir == DMA_DEV_TO_MEM) { | ||||
| 	if (uc->config.dir == DMA_DEV_TO_MEM) { | ||||
| 		uc->cfg_data.flow_id_base = uc->rflow->id; | ||||
| 		uc->cfg_data.flow_id_cnt = 1; | ||||
| 	} | ||||
|  | @ -1645,7 +1653,7 @@ static int udma_send(struct dma *dma, void *src, size_t len, void *metadata) | |||
| 	} | ||||
| 	uc = &ud->channels[dma->id]; | ||||
| 
 | ||||
| 	if (uc->dir != DMA_MEM_TO_DEV) | ||||
| 	if (uc->config.dir != DMA_MEM_TO_DEV) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	tc_ring_id = k3_nav_ringacc_get_ring_id(uc->tchan->tc_ring); | ||||
|  | @ -1655,8 +1663,8 @@ static int udma_send(struct dma *dma, void *src, size_t len, void *metadata) | |||
| 	cppi5_hdesc_reset_hbdesc(desc_tx); | ||||
| 
 | ||||
| 	cppi5_hdesc_init(desc_tx, | ||||
| 			 uc->needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0, | ||||
| 			 uc->psd_size); | ||||
| 			 uc->config.needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0, | ||||
| 			 uc->config.psd_size); | ||||
| 	cppi5_hdesc_set_pktlen(desc_tx, len); | ||||
| 	cppi5_hdesc_attach_buf(desc_tx, dma_src, len, dma_src, len); | ||||
| 	cppi5_desc_set_pktids(&desc_tx->hdr, uc->id, 0x3fff); | ||||
|  | @ -1669,7 +1677,7 @@ static int udma_send(struct dma *dma, void *src, size_t len, void *metadata) | |||
| 			   ALIGN((unsigned long)dma_src + len, | ||||
| 				 ARCH_DMA_MINALIGN)); | ||||
| 	flush_dcache_range((unsigned long)desc_tx, | ||||
| 			   ALIGN((unsigned long)desc_tx + uc->hdesc_size, | ||||
| 			   ALIGN((unsigned long)desc_tx + uc->config.hdesc_size, | ||||
| 				 ARCH_DMA_MINALIGN)); | ||||
| 
 | ||||
| 	ret = udma_push_to_ring(uc->tchan->t_ring, uc->desc_tx); | ||||
|  | @ -1687,6 +1695,7 @@ static int udma_send(struct dma *dma, void *src, size_t len, void *metadata) | |||
| static int udma_receive(struct dma *dma, void **dst, void *metadata) | ||||
| { | ||||
| 	struct udma_dev *ud = dev_get_priv(dma->dev); | ||||
| 	struct udma_chan_config *ucc; | ||||
| 	struct cppi5_host_desc_t *desc_rx; | ||||
| 	dma_addr_t buf_dma; | ||||
| 	struct udma_chan *uc; | ||||
|  | @ -1699,8 +1708,9 @@ static int udma_receive(struct dma *dma, void **dst, void *metadata) | |||
| 		return -EINVAL; | ||||
| 	} | ||||
| 	uc = &ud->channels[dma->id]; | ||||
| 	ucc = &uc->config; | ||||
| 
 | ||||
| 	if (uc->dir != DMA_DEV_TO_MEM) | ||||
| 	if (uc->config.dir != DMA_DEV_TO_MEM) | ||||
| 		return -EINVAL; | ||||
| 	if (!uc->num_rx_bufs) | ||||
| 		return -EINVAL; | ||||
|  | @ -1715,7 +1725,7 @@ static int udma_receive(struct dma *dma, void **dst, void *metadata) | |||
| 
 | ||||
| 	/* invalidate cache data */ | ||||
| 	invalidate_dcache_range((ulong)desc_rx, | ||||
| 				(ulong)(desc_rx + uc->hdesc_size)); | ||||
| 				(ulong)(desc_rx + ucc->hdesc_size)); | ||||
| 
 | ||||
| 	cppi5_hdesc_get_obuf(desc_rx, &buf_dma, &buf_dma_len); | ||||
| 	pkt_len = cppi5_hdesc_get_pktlen(desc_rx); | ||||
|  | @ -1734,6 +1744,7 @@ static int udma_receive(struct dma *dma, void **dst, void *metadata) | |||
| 
 | ||||
| static int udma_of_xlate(struct dma *dma, struct ofnode_phandle_args *args) | ||||
| { | ||||
| 	struct udma_chan_config *ucc; | ||||
| 	struct udma_dev *ud = dev_get_priv(dma->dev); | ||||
| 	struct udma_chan *uc = &ud->channels[0]; | ||||
| 	struct psil_endpoint_config *ep_config; | ||||
|  | @ -1748,32 +1759,40 @@ static int udma_of_xlate(struct dma *dma, struct ofnode_phandle_args *args) | |||
| 	if (val == ud->ch_count) | ||||
| 		return -EBUSY; | ||||
| 
 | ||||
| 	uc->slave_thread_id = args->args[0]; | ||||
| 	if (uc->slave_thread_id & K3_PSIL_DST_THREAD_ID_OFFSET) | ||||
| 		uc->dir = DMA_MEM_TO_DEV; | ||||
| 	ucc = &uc->config; | ||||
| 	ucc->remote_thread_id = args->args[0]; | ||||
| 	if (ucc->remote_thread_id & K3_PSIL_DST_THREAD_ID_OFFSET) | ||||
| 		ucc->dir = DMA_MEM_TO_DEV; | ||||
| 	else | ||||
| 		uc->dir = DMA_DEV_TO_MEM; | ||||
| 		ucc->dir = DMA_DEV_TO_MEM; | ||||
| 
 | ||||
| 	ep_config = psil_get_ep_config(uc->slave_thread_id); | ||||
| 	ep_config = psil_get_ep_config(ucc->remote_thread_id); | ||||
| 	if (IS_ERR(ep_config)) { | ||||
| 		dev_err(ud->dev, "No configuration for psi-l thread 0x%04x\n", | ||||
| 			uc->slave_thread_id); | ||||
| 		uc->dir = DMA_MEM_TO_MEM; | ||||
| 		uc->slave_thread_id = -1; | ||||
| 			uc->config.remote_thread_id); | ||||
| 		ucc->dir = DMA_MEM_TO_MEM; | ||||
| 		ucc->remote_thread_id = -1; | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	uc->pkt_mode = ep_config->pkt_mode; | ||||
| 	ucc->pkt_mode = ep_config->pkt_mode; | ||||
| 	ucc->channel_tpl = ep_config->channel_tpl; | ||||
| 	ucc->notdpkt = ep_config->notdpkt; | ||||
| 	ucc->ep_type = ep_config->ep_type; | ||||
| 
 | ||||
| 	uc->needs_epib = ep_config->needs_epib; | ||||
| 	uc->psd_size = ep_config->psd_size; | ||||
| 	uc->metadata_size = (uc->needs_epib ? CPPI5_INFO0_HDESC_EPIB_SIZE : 0) + uc->psd_size; | ||||
| 	ucc->needs_epib = ep_config->needs_epib; | ||||
| 	ucc->psd_size = ep_config->psd_size; | ||||
| 	ucc->metadata_size = (ucc->needs_epib ? CPPI5_INFO0_HDESC_EPIB_SIZE : 0) + ucc->psd_size; | ||||
| 
 | ||||
| 	ucc->hdesc_size = cppi5_hdesc_calc_size(ucc->needs_epib, | ||||
| 						ucc->psd_size, 0); | ||||
| 	ucc->hdesc_size = ALIGN(ucc->hdesc_size, ARCH_DMA_MINALIGN); | ||||
| 
 | ||||
| 	dma->id = uc->id; | ||||
| 	pr_debug("Allocated dma chn:%lu epib:%d psdata:%u meta:%u thread_id:%x\n", | ||||
| 		 dma->id, uc->needs_epib, | ||||
| 		 uc->psd_size, uc->metadata_size, | ||||
| 		 uc->slave_thread_id); | ||||
| 		 dma->id, ucc->needs_epib, | ||||
| 		 ucc->psd_size, ucc->metadata_size, | ||||
| 		 ucc->remote_thread_id); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -1792,26 +1811,26 @@ int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size) | |||
| 	} | ||||
| 	uc = &ud->channels[dma->id]; | ||||
| 
 | ||||
| 	if (uc->dir != DMA_DEV_TO_MEM) | ||||
| 	if (uc->config.dir != DMA_DEV_TO_MEM) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (uc->num_rx_bufs >= UDMA_RX_DESC_NUM) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	desc_num = uc->desc_rx_cur % UDMA_RX_DESC_NUM; | ||||
| 	desc_rx = uc->desc_rx + (desc_num * uc->hdesc_size); | ||||
| 	desc_rx = uc->desc_rx + (desc_num * uc->config.hdesc_size); | ||||
| 	dma_dst = (dma_addr_t)dst; | ||||
| 
 | ||||
| 	cppi5_hdesc_reset_hbdesc(desc_rx); | ||||
| 
 | ||||
| 	cppi5_hdesc_init(desc_rx, | ||||
| 			 uc->needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0, | ||||
| 			 uc->psd_size); | ||||
| 			 uc->config.needs_epib ? CPPI5_INFO0_HDESC_EPIB_PRESENT : 0, | ||||
| 			 uc->config.psd_size); | ||||
| 	cppi5_hdesc_set_pktlen(desc_rx, size); | ||||
| 	cppi5_hdesc_attach_buf(desc_rx, dma_dst, size, dma_dst, size); | ||||
| 
 | ||||
| 	flush_dcache_range((unsigned long)desc_rx, | ||||
| 			   ALIGN((unsigned long)desc_rx + uc->hdesc_size, | ||||
| 			   ALIGN((unsigned long)desc_rx + uc->config.hdesc_size, | ||||
| 				 ARCH_DMA_MINALIGN)); | ||||
| 
 | ||||
| 	udma_push_to_ring(uc->rchan->fd_ring, desc_rx); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue