@@ -79,6 +79,32 @@ axi_chan_iowrite64(struct axi_dma_chan *chan, u32 reg, u64 val)
79
79
iowrite32 (upper_32_bits (val ), chan -> chan_regs + reg + 4 );
80
80
}
81
81
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
+
82
108
static inline void axi_dma_disable (struct axi_dma_chip * chip )
83
109
{
84
110
u32 val ;
@@ -154,7 +180,10 @@ static inline void axi_chan_disable(struct axi_dma_chan *chan)
154
180
155
181
val = axi_dma_ioread32 (chan -> chip , DMAC_CHEN );
156
182
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 ;
158
187
axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
159
188
}
160
189
@@ -163,8 +192,12 @@ static inline void axi_chan_enable(struct axi_dma_chan *chan)
163
192
u32 val ;
164
193
165
194
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 ;
168
201
axi_dma_iowrite32 (chan -> chip , DMAC_CHEN , val );
169
202
}
170
203
@@ -336,7 +369,8 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
336
369
struct axi_dma_desc * first )
337
370
{
338
371
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 ;
340
374
u8 lms = 0 ; /* Select AXI0 master for LLI fetching */
341
375
342
376
if (unlikely (axi_chan_is_hw_enable (chan ))) {
@@ -348,36 +382,32 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
348
382
349
383
axi_dma_enable (chan -> chip );
350
384
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 ;
359
391
switch (chan -> direction ) {
360
392
case DMA_MEM_TO_DEV :
361
393
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 ;
366
397
if (chan -> chip -> apb_regs )
367
- reg |= ( chan -> id << CH_CFG_H_DST_PER_POS ) ;
398
+ config . dst_per = chan -> id ;
368
399
break ;
369
400
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 ;
374
404
if (chan -> chip -> apb_regs )
375
- reg |= ( chan -> id << CH_CFG_H_SRC_PER_POS ) ;
405
+ config . src_per = chan -> id ;
376
406
break ;
377
407
default :
378
408
break ;
379
409
}
380
- axi_chan_iowrite32 (chan , CH_CFG_H , reg );
410
+ axi_chan_config_write (chan , & config );
381
411
382
412
write_chan_llp (chan , first -> hw_desc [0 ].llp | lms );
383
413
@@ -1120,10 +1150,17 @@ static int dma_chan_pause(struct dma_chan *dchan)
1120
1150
1121
1151
spin_lock_irqsave (& chan -> vc .lock , flags );
1122
1152
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
+ }
1127
1164
1128
1165
do {
1129
1166
if (axi_chan_irq_read (chan ) & DWAXIDMAC_IRQ_SUSPENDED )
@@ -1147,9 +1184,15 @@ static inline void axi_chan_resume(struct axi_dma_chan *chan)
1147
1184
u32 val ;
1148
1185
1149
1186
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
+ }
1153
1196
1154
1197
chan -> is_paused = false;
1155
1198
}
@@ -1241,6 +1284,8 @@ static int parse_device_properties(struct axi_dma_chip *chip)
1241
1284
return - EINVAL ;
1242
1285
1243
1286
chip -> dw -> hdata -> nr_channels = tmp ;
1287
+ if (tmp <= DMA_REG_MAP_CH_REF )
1288
+ chip -> dw -> hdata -> reg_map_8_channels = true;
1244
1289
1245
1290
ret = device_property_read_u32 (dev , "snps,dma-masters" , & tmp );
1246
1291
if (ret )
0 commit comments