@@ -79,6 +79,32 @@ axi_chan_iowrite64(struct axi_dma_chan *chan, u32 reg, u64 val)
7979 iowrite32 (upper_32_bits (val ), chan -> chan_regs + reg + 4 );
8080}
8181
82+ static inline void axi_chan_config_write (struct axi_dma_chan * chan ,
83+ struct axi_dma_chan_config * config )
84+ {
85+ u32 cfg_lo , cfg_hi ;
86+
87+ cfg_lo = (config -> dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
88+ config -> src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS );
89+ if (chan -> chip -> dw -> hdata -> reg_map_8_channels ) {
90+ cfg_hi = config -> tt_fc << CH_CFG_H_TT_FC_POS |
91+ config -> hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
92+ config -> hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
93+ config -> src_per << CH_CFG_H_SRC_PER_POS |
94+ config -> dst_per << CH_CFG_H_DST_PER_POS |
95+ config -> prior << CH_CFG_H_PRIORITY_POS ;
96+ } else {
97+ cfg_lo |= config -> src_per << CH_CFG2_L_SRC_PER_POS |
98+ config -> dst_per << CH_CFG2_L_DST_PER_POS ;
99+ cfg_hi = config -> tt_fc << CH_CFG2_H_TT_FC_POS |
100+ config -> hs_sel_src << CH_CFG2_H_HS_SEL_SRC_POS |
101+ config -> hs_sel_dst << CH_CFG2_H_HS_SEL_DST_POS |
102+ config -> prior << CH_CFG2_H_PRIORITY_POS ;
103+ }
104+ axi_chan_iowrite32 (chan , CH_CFG_L , cfg_lo );
105+ axi_chan_iowrite32 (chan , CH_CFG_H , cfg_hi );
106+ }
107+
82108static inline void axi_dma_disable (struct axi_dma_chip * chip )
83109{
84110 u32 val ;
@@ -154,7 +180,10 @@ static inline void axi_chan_disable(struct axi_dma_chan *chan)
154180
155181 val = axi_dma_ioread32 (chan -> chip , DMAC_CHEN );
156182 val &= ~(BIT (chan -> id ) << DMAC_CHAN_EN_SHIFT );
157- val |= BIT (chan -> id ) << DMAC_CHAN_EN_WE_SHIFT ;
183+ if (chan -> chip -> dw -> hdata -> reg_map_8_channels )
184+ val |= BIT (chan -> id ) << DMAC_CHAN_EN_WE_SHIFT ;
185+ else
186+ val |= BIT (chan -> id ) << DMAC_CHAN_EN2_WE_SHIFT ;
158187 axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
159188}
160189
@@ -163,8 +192,12 @@ static inline void axi_chan_enable(struct axi_dma_chan *chan)
163192 u32 val ;
164193
165194 val = axi_dma_ioread32 (chan -> chip , DMAC_CHEN );
166- val |= BIT (chan -> id ) << DMAC_CHAN_EN_SHIFT |
167- BIT (chan -> id ) << DMAC_CHAN_EN_WE_SHIFT ;
195+ if (chan -> chip -> dw -> hdata -> reg_map_8_channels )
196+ val |= BIT (chan -> id ) << DMAC_CHAN_EN_SHIFT |
197+ BIT (chan -> id ) << DMAC_CHAN_EN_WE_SHIFT ;
198+ else
199+ val |= BIT (chan -> id ) << DMAC_CHAN_EN_SHIFT |
200+ BIT (chan -> id ) << DMAC_CHAN_EN2_WE_SHIFT ;
168201 axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
169202}
170203
@@ -336,7 +369,8 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
336369 struct axi_dma_desc * first )
337370{
338371 u32 priority = chan -> chip -> dw -> hdata -> priority [chan -> id ];
339- u32 reg , irq_mask ;
372+ struct axi_dma_chan_config config ;
373+ u32 irq_mask ;
340374 u8 lms = 0 ; /* Select AXI0 master for LLI fetching */
341375
342376 if (unlikely (axi_chan_is_hw_enable (chan ))) {
@@ -348,36 +382,32 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
348382
349383 axi_dma_enable (chan -> chip );
350384
351- reg = (DWAXIDMAC_MBLK_TYPE_LL << CH_CFG_L_DST_MULTBLK_TYPE_POS |
352- DWAXIDMAC_MBLK_TYPE_LL << CH_CFG_L_SRC_MULTBLK_TYPE_POS );
353- axi_chan_iowrite32 (chan , CH_CFG_L , reg );
354-
355- reg = (DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC << CH_CFG_H_TT_FC_POS |
356- priority << CH_CFG_H_PRIORITY_POS |
357- DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_DST_POS |
358- DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_SRC_POS );
385+ config .dst_multblk_type = DWAXIDMAC_MBLK_TYPE_LL ;
386+ config .src_multblk_type = DWAXIDMAC_MBLK_TYPE_LL ;
387+ config .tt_fc = DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC ;
388+ config .prior = priority ;
389+ config .hs_sel_dst = DWAXIDMAC_HS_SEL_HW ;
390+ config .hs_sel_dst = DWAXIDMAC_HS_SEL_HW ;
359391 switch (chan -> direction ) {
360392 case DMA_MEM_TO_DEV :
361393 dw_axi_dma_set_byte_halfword (chan , true);
362- reg |= (chan -> config .device_fc ?
363- DWAXIDMAC_TT_FC_MEM_TO_PER_DST :
364- DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC )
365- << CH_CFG_H_TT_FC_POS ;
394+ config .tt_fc = chan -> config .device_fc ?
395+ DWAXIDMAC_TT_FC_MEM_TO_PER_DST :
396+ DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC ;
366397 if (chan -> chip -> apb_regs )
367- reg |= ( chan -> id << CH_CFG_H_DST_PER_POS ) ;
398+ config . dst_per = chan -> id ;
368399 break ;
369400 case DMA_DEV_TO_MEM :
370- reg |= (chan -> config .device_fc ?
371- DWAXIDMAC_TT_FC_PER_TO_MEM_SRC :
372- DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC )
373- << CH_CFG_H_TT_FC_POS ;
401+ config .tt_fc = chan -> config .device_fc ?
402+ DWAXIDMAC_TT_FC_PER_TO_MEM_SRC :
403+ DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC ;
374404 if (chan -> chip -> apb_regs )
375- reg |= ( chan -> id << CH_CFG_H_SRC_PER_POS ) ;
405+ config . src_per = chan -> id ;
376406 break ;
377407 default :
378408 break ;
379409 }
380- axi_chan_iowrite32 (chan , CH_CFG_H , reg );
410+ axi_chan_config_write (chan , & config );
381411
382412 write_chan_llp (chan , first -> hw_desc [0 ].llp | lms );
383413
@@ -1120,10 +1150,17 @@ static int dma_chan_pause(struct dma_chan *dchan)
11201150
11211151 spin_lock_irqsave (& chan -> vc .lock , flags );
11221152
1123- val = axi_dma_ioread32 (chan -> chip , DMAC_CHEN );
1124- val |= BIT (chan -> id ) << DMAC_CHAN_SUSP_SHIFT |
1125- BIT (chan -> id ) << DMAC_CHAN_SUSP_WE_SHIFT ;
1126- axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
1153+ if (chan -> chip -> dw -> hdata -> reg_map_8_channels ) {
1154+ val = axi_dma_ioread32 (chan -> chip , DMAC_CHEN );
1155+ val |= BIT (chan -> id ) << DMAC_CHAN_SUSP_SHIFT |
1156+ BIT (chan -> id ) << DMAC_CHAN_SUSP_WE_SHIFT ;
1157+ axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
1158+ } else {
1159+ val = 0 ;
1160+ val |= BIT (chan -> id ) << DMAC_CHAN_SUSP2_SHIFT |
1161+ BIT (chan -> id ) << DMAC_CHAN_SUSP2_WE_SHIFT ;
1162+ axi_dma_iowrite32 (chan -> chip , DMAC_CHSUSPREG , val );
1163+ }
11271164
11281165 do {
11291166 if (axi_chan_irq_read (chan ) & DWAXIDMAC_IRQ_SUSPENDED )
@@ -1147,9 +1184,15 @@ static inline void axi_chan_resume(struct axi_dma_chan *chan)
11471184 u32 val ;
11481185
11491186 val = axi_dma_ioread32 (chan -> chip , DMAC_CHEN );
1150- val &= ~(BIT (chan -> id ) << DMAC_CHAN_SUSP_SHIFT );
1151- val |= (BIT (chan -> id ) << DMAC_CHAN_SUSP_WE_SHIFT );
1152- axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
1187+ if (chan -> chip -> dw -> hdata -> reg_map_8_channels ) {
1188+ val &= ~(BIT (chan -> id ) << DMAC_CHAN_SUSP_SHIFT );
1189+ val |= (BIT (chan -> id ) << DMAC_CHAN_SUSP_WE_SHIFT );
1190+ axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
1191+ } else {
1192+ val &= ~(BIT (chan -> id ) << DMAC_CHAN_SUSP2_SHIFT );
1193+ val |= (BIT (chan -> id ) << DMAC_CHAN_SUSP2_WE_SHIFT );
1194+ axi_dma_iowrite32 (chan -> chip , DMAC_CHSUSPREG , val );
1195+ }
11531196
11541197 chan -> is_paused = false;
11551198}
@@ -1241,6 +1284,8 @@ static int parse_device_properties(struct axi_dma_chip *chip)
12411284 return - EINVAL ;
12421285
12431286 chip -> dw -> hdata -> nr_channels = tmp ;
1287+ if (tmp <= DMA_REG_MAP_CH_REF )
1288+ chip -> dw -> hdata -> reg_map_8_channels = true;
12441289
12451290 ret = device_property_read_u32 (dev , "snps,dma-masters" , & tmp );
12461291 if (ret )
0 commit comments