@@ -87,6 +87,20 @@ struct fsl_edma_hw_tcd {
8787 __le16 biter ;
8888};
8989
90+ struct fsl_edma_hw_tcd64 {
91+ __le64 saddr ;
92+ __le16 soff ;
93+ __le16 attr ;
94+ __le32 nbytes ;
95+ __le64 slast ;
96+ __le64 daddr ;
97+ __le64 dlast_sga ;
98+ __le16 doff ;
99+ __le16 citer ;
100+ __le16 csr ;
101+ __le16 biter ;
102+ } __packed ;
103+
90104struct fsl_edma3_ch_reg {
91105 __le32 ch_csr ;
92106 __le32 ch_es ;
@@ -96,7 +110,10 @@ struct fsl_edma3_ch_reg {
96110 __le32 ch_mux ;
97111 __le32 ch_mattr ; /* edma4, reserved for edma3 */
98112 __le32 ch_reserved ;
99- struct fsl_edma_hw_tcd tcd ;
113+ union {
114+ struct fsl_edma_hw_tcd tcd ;
115+ struct fsl_edma_hw_tcd64 tcd64 ;
116+ };
100117} __packed ;
101118
102119/*
@@ -125,7 +142,7 @@ struct edma_regs {
125142
126143struct fsl_edma_sw_tcd {
127144 dma_addr_t ptcd ;
128- struct fsl_edma_hw_tcd * vtcd ;
145+ void * vtcd ;
129146};
130147
131148struct fsl_edma_chan {
@@ -144,7 +161,7 @@ struct fsl_edma_chan {
144161 u32 dma_dev_size ;
145162 enum dma_data_direction dma_dir ;
146163 char chan_name [32 ];
147- struct fsl_edma_hw_tcd __iomem * tcd ;
164+ void __iomem * tcd ;
148165 void __iomem * mux_addr ;
149166 u32 real_count ;
150167 struct work_struct issue_worker ;
@@ -188,6 +205,7 @@ struct fsl_edma_desc {
188205#define FSL_EDMA_DRV_CLEAR_DONE_E_SG BIT(13)
189206/* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
190207#define FSL_EDMA_DRV_CLEAR_DONE_E_LINK BIT(14)
208+ #define FSL_EDMA_DRV_TCD64 BIT(15)
191209
192210#define FSL_EDMA_DRV_EDMA3 (FSL_EDMA_DRV_SPLIT_REG | \
193211 FSL_EDMA_DRV_BUS_8BYTE | \
@@ -231,18 +249,61 @@ struct fsl_edma_engine {
231249 struct fsl_edma_chan chans [] __counted_by (n_chans );
232250};
233251
234- #define edma_read_tcdreg (chan , __name ) \
235- (sizeof(chan->tcd->__name) == sizeof(u32) ? \
236- edma_readl(chan->edma, &chan->tcd->__name) : \
237- edma_readw(chan->edma, &chan->tcd->__name))
252+ #define edma_read_tcdreg_c (chan , _tcd , __name ) \
253+ (sizeof((_tcd)->__name) == sizeof(u64) ? \
254+ edma_readq(chan->edma, &(_tcd)->__name) : \
255+ ((sizeof((_tcd)->__name) == sizeof(u32)) ? \
256+ edma_readl(chan->edma, &(_tcd)->__name) : \
257+ edma_readw(chan->edma, &(_tcd)->__name) \
258+ ))
259+
260+ #define edma_read_tcdreg (chan , __name ) \
261+ ((fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) ? \
262+ edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd64 __iomem *)chan->tcd), __name) : \
263+ edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd __iomem *)chan->tcd), __name) \
264+ )
265+
266+ #define edma_write_tcdreg_c (chan , _tcd , _val , __name ) \
267+ do { \
268+ switch (sizeof(_tcd->__name)) { \
269+ case sizeof(u64): \
270+ edma_writeq(chan->edma, (u64 __force)_val, &_tcd->__name); \
271+ break; \
272+ case sizeof(u32): \
273+ edma_writel(chan->edma, (u32 __force)_val, &_tcd->__name); \
274+ break; \
275+ case sizeof(u16): \
276+ edma_writew(chan->edma, (u16 __force)_val, &_tcd->__name); \
277+ break; \
278+ case sizeof(u8): \
279+ edma_writeb(chan->edma, (u8 __force)_val, &_tcd->__name); \
280+ break; \
281+ } \
282+ } while (0)
238283
239- #define edma_write_tcdreg (chan , val , __name ) \
240- (sizeof(chan->tcd->__name) == sizeof(u32) ? \
241- edma_writel(chan->edma, (u32 __force)val, &chan->tcd->__name) : \
242- edma_writew(chan->edma, (u16 __force)val, &chan->tcd->__name))
284+ #define edma_write_tcdreg (chan , val , __name ) \
285+ do { \
286+ struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
287+ struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd __iomem *)chan->tcd; \
288+ \
289+ if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) \
290+ edma_write_tcdreg_c(chan, tcd64_r, val, __name); \
291+ else \
292+ edma_write_tcdreg_c(chan, tcd_r, val, __name); \
293+ } while (0)
243294
244- #define edma_cp_tcd_to_reg (chan , __tcd , __name ) \
245- edma_write_tcdreg(chan, __tcd->__name, __name)
295+ #define edma_cp_tcd_to_reg (chan , __tcd , __name ) \
296+ do { \
297+ struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
298+ struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd __iomem *)chan->tcd; \
299+ struct fsl_edma_hw_tcd64 *tcd64_m = (struct fsl_edma_hw_tcd64 *)__tcd; \
300+ struct fsl_edma_hw_tcd *tcd_m = (struct fsl_edma_hw_tcd *)__tcd; \
301+ \
302+ if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) \
303+ edma_write_tcdreg_c(chan, tcd64_r, tcd64_m->__name, __name); \
304+ else \
305+ edma_write_tcdreg_c(chan, tcd_r, tcd_m->__name, __name); \
306+ } while (0)
246307
247308#define edma_readl_chreg (chan , __name ) \
248309 edma_readl(chan->edma, \
@@ -254,24 +315,41 @@ struct fsl_edma_engine {
254315 (void __iomem *)&(container_of(((__force void *)chan->tcd),\
255316 struct fsl_edma3_ch_reg, tcd)->__name))
256317
257- #define fsl_edma_get_tcd (_chan , _tcd , _field ) ((_tcd)->_field)
258-
259- #define fsl_edma_le_to_cpu (x ) \
260- (sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) : le16_to_cpu((__force __le16)(x)))
261-
262- #define fsl_edma_get_tcd_to_cpu (_chan , _tcd , _field ) \
263- fsl_edma_le_to_cpu(fsl_edma_get_tcd(_chan, _tcd, _field))
318+ #define fsl_edma_get_tcd (_chan , _tcd , _field ) \
319+ (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ? (((struct fsl_edma_hw_tcd64 *)_tcd)->_field) : \
320+ (((struct fsl_edma_hw_tcd *)_tcd)->_field))
321+
322+ #define fsl_edma_le_to_cpu (x ) \
323+ (sizeof(x) == sizeof(u64) ? le64_to_cpu((__force __le64)(x)) : \
324+ (sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) : \
325+ le16_to_cpu((__force __le16)(x))))
326+
327+ #define fsl_edma_get_tcd_to_cpu (_chan , _tcd , _field ) \
328+ (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ? \
329+ fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd64 *)_tcd)->_field) : \
330+ fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd *)_tcd)->_field))
331+
332+ #define fsl_edma_set_tcd_to_le_c (_tcd , _val , _field ) \
333+ do { \
334+ switch (sizeof((_tcd)->_field)) { \
335+ case sizeof(u64): \
336+ *(__force __le64 *)(&((_tcd)->_field)) = cpu_to_le64(_val); \
337+ break; \
338+ case sizeof(u32): \
339+ *(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val); \
340+ break; \
341+ case sizeof(u16): \
342+ *(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val); \
343+ break; \
344+ } \
345+ } while (0)
264346
265- #define fsl_edma_set_tcd_to_le (_fsl_chan , _tcd , _val , _field ) \
266- do { \
267- switch (sizeof((_tcd)->_field)) { \
268- case sizeof(u32): \
269- *(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val); \
270- break; \
271- case sizeof(u16): \
272- *(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val); \
273- break; \
274- } \
347+ #define fsl_edma_set_tcd_to_le (_chan , _tcd , _val , _field ) \
348+ do { \
349+ if (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64) \
350+ fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd64 *)_tcd, _val, _field); \
351+ else \
352+ fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd *)_tcd, _val, _field); \
275353} while (0)
276354
277355/*
@@ -280,6 +358,21 @@ do { \
280358 * For the big-endian IP module, the offset for 8-bit or 16-bit registers
281359 * should also be swapped opposite to that in little-endian IP.
282360 */
361+ static inline u64 edma_readq (struct fsl_edma_engine * edma , void __iomem * addr )
362+ {
363+ u64 l , h ;
364+
365+ if (edma -> big_endian ) {
366+ l = ioread32be (addr );
367+ h = ioread32be (addr + 4 );
368+ } else {
369+ l = ioread32 (addr );
370+ h = ioread32 (addr + 4 );
371+ }
372+
373+ return (h << 32 ) | l ;
374+ }
375+
283376static inline u32 edma_readl (struct fsl_edma_engine * edma , void __iomem * addr )
284377{
285378 if (edma -> big_endian )
@@ -325,6 +418,18 @@ static inline void edma_writel(struct fsl_edma_engine *edma,
325418 iowrite32 (val , addr );
326419}
327420
421+ static inline void edma_writeq (struct fsl_edma_engine * edma ,
422+ u64 val , void __iomem * addr )
423+ {
424+ if (edma -> big_endian ) {
425+ iowrite32be (val & 0xFFFFFFFF , addr );
426+ iowrite32be (val >> 32 , addr + 4 );
427+ } else {
428+ iowrite32 (val & 0xFFFFFFFF , addr );
429+ iowrite32 (val >> 32 , addr + 4 );
430+ }
431+ }
432+
328433static inline struct fsl_edma_chan * to_fsl_edma_chan (struct dma_chan * chan )
329434{
330435 return container_of (chan , struct fsl_edma_chan , vchan .chan );
0 commit comments