1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*******************************************************************************
3*4882a593Smuzhiyun Header File to describe Normal/enhanced descriptor functions used for RING
4*4882a593Smuzhiyun and CHAINED modes.
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun Copyright(C) 2011 STMicroelectronics Ltd
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun It defines all the functions used to handle the normal/enhanced
9*4882a593Smuzhiyun descriptors in case of the DMA is configured to work in chained or
10*4882a593Smuzhiyun in ring mode.
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
14*4882a593Smuzhiyun *******************************************************************************/
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #ifndef __DESC_COM_H__
17*4882a593Smuzhiyun #define __DESC_COM_H__
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /* Specific functions used for Ring mode */
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /* Enhanced descriptors */
ehn_desc_rx_set_on_ring(struct dma_desc * p,int end,int bfsize)22*4882a593Smuzhiyun static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end,
23*4882a593Smuzhiyun int bfsize)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun if (bfsize == BUF_SIZE_16KiB)
26*4882a593Smuzhiyun p->des1 |= cpu_to_le32((BUF_SIZE_8KiB
27*4882a593Smuzhiyun << ERDES1_BUFFER2_SIZE_SHIFT)
28*4882a593Smuzhiyun & ERDES1_BUFFER2_SIZE_MASK);
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun if (end)
31*4882a593Smuzhiyun p->des1 |= cpu_to_le32(ERDES1_END_RING);
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun
enh_desc_end_tx_desc_on_ring(struct dma_desc * p,int end)34*4882a593Smuzhiyun static inline void enh_desc_end_tx_desc_on_ring(struct dma_desc *p, int end)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun if (end)
37*4882a593Smuzhiyun p->des0 |= cpu_to_le32(ETDES0_END_RING);
38*4882a593Smuzhiyun else
39*4882a593Smuzhiyun p->des0 &= cpu_to_le32(~ETDES0_END_RING);
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun
enh_set_tx_desc_len_on_ring(struct dma_desc * p,int len)42*4882a593Smuzhiyun static inline void enh_set_tx_desc_len_on_ring(struct dma_desc *p, int len)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun if (unlikely(len > BUF_SIZE_4KiB)) {
45*4882a593Smuzhiyun p->des1 |= cpu_to_le32((((len - BUF_SIZE_4KiB)
46*4882a593Smuzhiyun << ETDES1_BUFFER2_SIZE_SHIFT)
47*4882a593Smuzhiyun & ETDES1_BUFFER2_SIZE_MASK) | (BUF_SIZE_4KiB
48*4882a593Smuzhiyun & ETDES1_BUFFER1_SIZE_MASK));
49*4882a593Smuzhiyun } else
50*4882a593Smuzhiyun p->des1 |= cpu_to_le32((len & ETDES1_BUFFER1_SIZE_MASK));
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /* Normal descriptors */
ndesc_rx_set_on_ring(struct dma_desc * p,int end,int bfsize)54*4882a593Smuzhiyun static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end, int bfsize)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun if (bfsize >= BUF_SIZE_2KiB) {
57*4882a593Smuzhiyun int bfsize2;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun bfsize2 = min(bfsize - BUF_SIZE_2KiB + 1, BUF_SIZE_2KiB - 1);
60*4882a593Smuzhiyun p->des1 |= cpu_to_le32((bfsize2 << RDES1_BUFFER2_SIZE_SHIFT)
61*4882a593Smuzhiyun & RDES1_BUFFER2_SIZE_MASK);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun if (end)
65*4882a593Smuzhiyun p->des1 |= cpu_to_le32(RDES1_END_RING);
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
ndesc_end_tx_desc_on_ring(struct dma_desc * p,int end)68*4882a593Smuzhiyun static inline void ndesc_end_tx_desc_on_ring(struct dma_desc *p, int end)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun if (end)
71*4882a593Smuzhiyun p->des1 |= cpu_to_le32(TDES1_END_RING);
72*4882a593Smuzhiyun else
73*4882a593Smuzhiyun p->des1 &= cpu_to_le32(~TDES1_END_RING);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
norm_set_tx_desc_len_on_ring(struct dma_desc * p,int len)76*4882a593Smuzhiyun static inline void norm_set_tx_desc_len_on_ring(struct dma_desc *p, int len)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun if (unlikely(len > BUF_SIZE_2KiB)) {
79*4882a593Smuzhiyun unsigned int buffer1 = (BUF_SIZE_2KiB - 1)
80*4882a593Smuzhiyun & TDES1_BUFFER1_SIZE_MASK;
81*4882a593Smuzhiyun p->des1 |= cpu_to_le32((((len - buffer1)
82*4882a593Smuzhiyun << TDES1_BUFFER2_SIZE_SHIFT)
83*4882a593Smuzhiyun & TDES1_BUFFER2_SIZE_MASK) | buffer1);
84*4882a593Smuzhiyun } else
85*4882a593Smuzhiyun p->des1 |= cpu_to_le32((len & TDES1_BUFFER1_SIZE_MASK));
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /* Specific functions used for Chain mode */
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /* Enhanced descriptors */
ehn_desc_rx_set_on_chain(struct dma_desc * p)91*4882a593Smuzhiyun static inline void ehn_desc_rx_set_on_chain(struct dma_desc *p)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun p->des1 |= cpu_to_le32(ERDES1_SECOND_ADDRESS_CHAINED);
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun
enh_desc_end_tx_desc_on_chain(struct dma_desc * p)96*4882a593Smuzhiyun static inline void enh_desc_end_tx_desc_on_chain(struct dma_desc *p)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun p->des0 |= cpu_to_le32(ETDES0_SECOND_ADDRESS_CHAINED);
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
enh_set_tx_desc_len_on_chain(struct dma_desc * p,int len)101*4882a593Smuzhiyun static inline void enh_set_tx_desc_len_on_chain(struct dma_desc *p, int len)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun p->des1 |= cpu_to_le32(len & ETDES1_BUFFER1_SIZE_MASK);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /* Normal descriptors */
ndesc_rx_set_on_chain(struct dma_desc * p,int end)107*4882a593Smuzhiyun static inline void ndesc_rx_set_on_chain(struct dma_desc *p, int end)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun p->des1 |= cpu_to_le32(RDES1_SECOND_ADDRESS_CHAINED);
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun
ndesc_tx_set_on_chain(struct dma_desc * p)112*4882a593Smuzhiyun static inline void ndesc_tx_set_on_chain(struct dma_desc *p)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun p->des1 |= cpu_to_le32(TDES1_SECOND_ADDRESS_CHAINED);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
norm_set_tx_desc_len_on_chain(struct dma_desc * p,int len)117*4882a593Smuzhiyun static inline void norm_set_tx_desc_len_on_chain(struct dma_desc *p, int len)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun p->des1 |= cpu_to_le32(len & TDES1_BUFFER1_SIZE_MASK);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun #endif /* __DESC_COM_H__ */
122