13
13
#include <linux/interrupt.h>
14
14
#include <linux/module.h>
15
15
#include <linux/of_dma.h>
16
+ #include <linux/of_device.h>
16
17
#include <linux/platform_device.h>
17
18
#include <linux/slab.h>
18
19
#include <linux/spinlock.h>
31
32
#define SUN4I_DMA_CFG_SRC_ADDR_MODE (mode ) ((mode) << 5)
32
33
#define SUN4I_DMA_CFG_SRC_DRQ_TYPE (type ) (type)
33
34
35
+ #define SUN4I_MAX_BURST 8
36
+
34
37
/** Normal DMA register values **/
35
38
36
39
/* Normal DMA source/destination data request type values */
132
135
#define SUN4I_DDMA_MAX_SEG_SIZE SZ_16M
133
136
#define SUN4I_DMA_MAX_SEG_SIZE SUN4I_NDMA_MAX_SEG_SIZE
134
137
138
+ /*
139
+ * Hardware channels / ports representation
140
+ *
141
+ * The hardware is used in several SoCs, with differing numbers
142
+ * of channels and endpoints. This structure ties those numbers
143
+ * to a certain compatible string.
144
+ */
145
+ struct sun4i_dma_config {
146
+ u32 ndma_nr_max_channels ;
147
+ u32 ndma_nr_max_vchans ;
148
+
149
+ u32 ddma_nr_max_channels ;
150
+ u32 ddma_nr_max_vchans ;
151
+
152
+ u32 dma_nr_max_channels ;
153
+
154
+ void (* set_dst_data_width )(u32 * p_cfg , s8 data_width );
155
+ void (* set_src_data_width )(u32 * p_cfg , s8 data_width );
156
+ int (* convert_burst )(u32 maxburst );
157
+
158
+ u8 ndma_drq_sdram ;
159
+ u8 ddma_drq_sdram ;
160
+
161
+ u8 max_burst ;
162
+ };
163
+
135
164
struct sun4i_dma_pchan {
136
165
/* Register base of channel */
137
166
void __iomem * base ;
@@ -170,14 +199,15 @@ struct sun4i_dma_contract {
170
199
};
171
200
172
201
struct sun4i_dma_dev {
173
- DECLARE_BITMAP ( pchans_used , SUN4I_DMA_NR_MAX_CHANNELS ) ;
202
+ unsigned long * pchans_used ;
174
203
struct dma_device slave ;
175
204
struct sun4i_dma_pchan * pchans ;
176
205
struct sun4i_dma_vchan * vchans ;
177
206
void __iomem * base ;
178
207
struct clk * clk ;
179
208
int irq ;
180
209
spinlock_t lock ;
210
+ const struct sun4i_dma_config * cfg ;
181
211
};
182
212
183
213
static struct sun4i_dma_dev * to_sun4i_dma_dev (struct dma_device * dev )
@@ -200,7 +230,17 @@ static struct device *chan2dev(struct dma_chan *chan)
200
230
return & chan -> dev -> device ;
201
231
}
202
232
203
- static int convert_burst (u32 maxburst )
233
+ static void set_dst_data_width_a10 (u32 * p_cfg , s8 data_width )
234
+ {
235
+ * p_cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH (data_width );
236
+ }
237
+
238
+ static void set_src_data_width_a10 (u32 * p_cfg , s8 data_width )
239
+ {
240
+ * p_cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH (data_width );
241
+ }
242
+
243
+ static int convert_burst_a10 (u32 maxburst )
204
244
{
205
245
if (maxburst > 8 )
206
246
return - EINVAL ;
@@ -233,15 +273,15 @@ static struct sun4i_dma_pchan *find_and_use_pchan(struct sun4i_dma_dev *priv,
233
273
int i , max ;
234
274
235
275
/*
236
- * pchans 0-SUN4I_NDMA_NR_MAX_CHANNELS are normal, and
237
- * SUN4I_NDMA_NR_MAX_CHANNELS + are dedicated ones
276
+ * pchans 0-priv->cfg->ndma_nr_max_channels are normal, and
277
+ * priv->cfg->ndma_nr_max_channels + are dedicated ones
238
278
*/
239
279
if (vchan -> is_dedicated ) {
240
- i = SUN4I_NDMA_NR_MAX_CHANNELS ;
241
- max = SUN4I_DMA_NR_MAX_CHANNELS ;
280
+ i = priv -> cfg -> ndma_nr_max_channels ;
281
+ max = priv -> cfg -> dma_nr_max_channels ;
242
282
} else {
243
283
i = 0 ;
244
- max = SUN4I_NDMA_NR_MAX_CHANNELS ;
284
+ max = priv -> cfg -> ndma_nr_max_channels ;
245
285
}
246
286
247
287
spin_lock_irqsave (& priv -> lock , flags );
@@ -444,6 +484,7 @@ generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,
444
484
size_t len , struct dma_slave_config * sconfig ,
445
485
enum dma_transfer_direction direction )
446
486
{
487
+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
447
488
struct sun4i_dma_promise * promise ;
448
489
int ret ;
449
490
@@ -467,13 +508,13 @@ generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,
467
508
sconfig -> src_addr_width , sconfig -> dst_addr_width );
468
509
469
510
/* Source burst */
470
- ret = convert_burst (sconfig -> src_maxburst );
511
+ ret = priv -> cfg -> convert_burst (sconfig -> src_maxburst );
471
512
if (ret < 0 )
472
513
goto fail ;
473
514
promise -> cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH (ret );
474
515
475
516
/* Destination burst */
476
- ret = convert_burst (sconfig -> dst_maxburst );
517
+ ret = priv -> cfg -> convert_burst (sconfig -> dst_maxburst );
477
518
if (ret < 0 )
478
519
goto fail ;
479
520
promise -> cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH (ret );
@@ -482,13 +523,13 @@ generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,
482
523
ret = convert_buswidth (sconfig -> src_addr_width );
483
524
if (ret < 0 )
484
525
goto fail ;
485
- promise -> cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH ( ret );
526
+ priv -> cfg -> set_src_data_width ( & promise -> cfg , ret );
486
527
487
528
/* Destination bus width */
488
529
ret = convert_buswidth (sconfig -> dst_addr_width );
489
530
if (ret < 0 )
490
531
goto fail ;
491
- promise -> cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH ( ret );
532
+ priv -> cfg -> set_dst_data_width ( & promise -> cfg , ret );
492
533
493
534
return promise ;
494
535
@@ -510,6 +551,7 @@ static struct sun4i_dma_promise *
510
551
generate_ddma_promise (struct dma_chan * chan , dma_addr_t src , dma_addr_t dest ,
511
552
size_t len , struct dma_slave_config * sconfig )
512
553
{
554
+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
513
555
struct sun4i_dma_promise * promise ;
514
556
int ret ;
515
557
@@ -524,13 +566,13 @@ generate_ddma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,
524
566
SUN4I_DDMA_CFG_BYTE_COUNT_MODE_REMAIN ;
525
567
526
568
/* Source burst */
527
- ret = convert_burst (sconfig -> src_maxburst );
569
+ ret = priv -> cfg -> convert_burst (sconfig -> src_maxburst );
528
570
if (ret < 0 )
529
571
goto fail ;
530
572
promise -> cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH (ret );
531
573
532
574
/* Destination burst */
533
- ret = convert_burst (sconfig -> dst_maxburst );
575
+ ret = priv -> cfg -> convert_burst (sconfig -> dst_maxburst );
534
576
if (ret < 0 )
535
577
goto fail ;
536
578
promise -> cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH (ret );
@@ -539,13 +581,13 @@ generate_ddma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,
539
581
ret = convert_buswidth (sconfig -> src_addr_width );
540
582
if (ret < 0 )
541
583
goto fail ;
542
- promise -> cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH ( ret );
584
+ priv -> cfg -> set_src_data_width ( & promise -> cfg , ret );
543
585
544
586
/* Destination bus width */
545
587
ret = convert_buswidth (sconfig -> dst_addr_width );
546
588
if (ret < 0 )
547
589
goto fail ;
548
- promise -> cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH ( ret );
590
+ priv -> cfg -> set_dst_data_width ( & promise -> cfg , ret );
549
591
550
592
return promise ;
551
593
@@ -622,6 +664,7 @@ static struct dma_async_tx_descriptor *
622
664
sun4i_dma_prep_dma_memcpy (struct dma_chan * chan , dma_addr_t dest ,
623
665
dma_addr_t src , size_t len , unsigned long flags )
624
666
{
667
+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
625
668
struct sun4i_dma_vchan * vchan = to_sun4i_dma_vchan (chan );
626
669
struct dma_slave_config * sconfig = & vchan -> cfg ;
627
670
struct sun4i_dma_promise * promise ;
@@ -638,8 +681,8 @@ sun4i_dma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest,
638
681
*/
639
682
sconfig -> src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
640
683
sconfig -> dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
641
- sconfig -> src_maxburst = 8 ;
642
- sconfig -> dst_maxburst = 8 ;
684
+ sconfig -> src_maxburst = priv -> cfg -> max_burst ;
685
+ sconfig -> dst_maxburst = priv -> cfg -> max_burst ;
643
686
644
687
if (vchan -> is_dedicated )
645
688
promise = generate_ddma_promise (chan , src , dest , len , sconfig );
@@ -654,11 +697,13 @@ sun4i_dma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest,
654
697
655
698
/* Configure memcpy mode */
656
699
if (vchan -> is_dedicated ) {
657
- promise -> cfg |= SUN4I_DMA_CFG_SRC_DRQ_TYPE (SUN4I_DDMA_DRQ_TYPE_SDRAM ) |
658
- SUN4I_DMA_CFG_DST_DRQ_TYPE (SUN4I_DDMA_DRQ_TYPE_SDRAM );
700
+ promise -> cfg |=
701
+ SUN4I_DMA_CFG_SRC_DRQ_TYPE (priv -> cfg -> ddma_drq_sdram ) |
702
+ SUN4I_DMA_CFG_DST_DRQ_TYPE (priv -> cfg -> ddma_drq_sdram );
659
703
} else {
660
- promise -> cfg |= SUN4I_DMA_CFG_SRC_DRQ_TYPE (SUN4I_NDMA_DRQ_TYPE_SDRAM ) |
661
- SUN4I_DMA_CFG_DST_DRQ_TYPE (SUN4I_NDMA_DRQ_TYPE_SDRAM );
704
+ promise -> cfg |=
705
+ SUN4I_DMA_CFG_SRC_DRQ_TYPE (priv -> cfg -> ndma_drq_sdram ) |
706
+ SUN4I_DMA_CFG_DST_DRQ_TYPE (priv -> cfg -> ndma_drq_sdram );
662
707
}
663
708
664
709
/* Fill the contract with our only promise */
@@ -673,6 +718,7 @@ sun4i_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf, size_t len,
673
718
size_t period_len , enum dma_transfer_direction dir ,
674
719
unsigned long flags )
675
720
{
721
+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
676
722
struct sun4i_dma_vchan * vchan = to_sun4i_dma_vchan (chan );
677
723
struct dma_slave_config * sconfig = & vchan -> cfg ;
678
724
struct sun4i_dma_promise * promise ;
@@ -696,11 +742,11 @@ sun4i_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf, size_t len,
696
742
if (vchan -> is_dedicated ) {
697
743
io_mode = SUN4I_DDMA_ADDR_MODE_IO ;
698
744
linear_mode = SUN4I_DDMA_ADDR_MODE_LINEAR ;
699
- ram_type = SUN4I_DDMA_DRQ_TYPE_SDRAM ;
745
+ ram_type = priv -> cfg -> ddma_drq_sdram ;
700
746
} else {
701
747
io_mode = SUN4I_NDMA_ADDR_MODE_IO ;
702
748
linear_mode = SUN4I_NDMA_ADDR_MODE_LINEAR ;
703
- ram_type = SUN4I_NDMA_DRQ_TYPE_SDRAM ;
749
+ ram_type = priv -> cfg -> ndma_drq_sdram ;
704
750
}
705
751
706
752
if (dir == DMA_MEM_TO_DEV ) {
@@ -793,6 +839,7 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
793
839
unsigned int sg_len , enum dma_transfer_direction dir ,
794
840
unsigned long flags , void * context )
795
841
{
842
+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
796
843
struct sun4i_dma_vchan * vchan = to_sun4i_dma_vchan (chan );
797
844
struct dma_slave_config * sconfig = & vchan -> cfg ;
798
845
struct sun4i_dma_promise * promise ;
@@ -818,11 +865,11 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
818
865
if (vchan -> is_dedicated ) {
819
866
io_mode = SUN4I_DDMA_ADDR_MODE_IO ;
820
867
linear_mode = SUN4I_DDMA_ADDR_MODE_LINEAR ;
821
- ram_type = SUN4I_DDMA_DRQ_TYPE_SDRAM ;
868
+ ram_type = priv -> cfg -> ddma_drq_sdram ;
822
869
} else {
823
870
io_mode = SUN4I_NDMA_ADDR_MODE_IO ;
824
871
linear_mode = SUN4I_NDMA_ADDR_MODE_LINEAR ;
825
- ram_type = SUN4I_NDMA_DRQ_TYPE_SDRAM ;
872
+ ram_type = priv -> cfg -> ndma_drq_sdram ;
826
873
}
827
874
828
875
if (dir == DMA_MEM_TO_DEV )
@@ -1150,6 +1197,10 @@ static int sun4i_dma_probe(struct platform_device *pdev)
1150
1197
if (!priv )
1151
1198
return - ENOMEM ;
1152
1199
1200
+ priv -> cfg = of_device_get_match_data (& pdev -> dev );
1201
+ if (!priv -> cfg )
1202
+ return - ENODEV ;
1203
+
1153
1204
priv -> base = devm_platform_ioremap_resource (pdev , 0 );
1154
1205
if (IS_ERR (priv -> base ))
1155
1206
return PTR_ERR (priv -> base );
@@ -1197,23 +1248,26 @@ static int sun4i_dma_probe(struct platform_device *pdev)
1197
1248
1198
1249
priv -> slave .dev = & pdev -> dev ;
1199
1250
1200
- priv -> pchans = devm_kcalloc (& pdev -> dev , SUN4I_DMA_NR_MAX_CHANNELS ,
1251
+ priv -> pchans = devm_kcalloc (& pdev -> dev , priv -> cfg -> dma_nr_max_channels ,
1201
1252
sizeof (struct sun4i_dma_pchan ), GFP_KERNEL );
1202
1253
priv -> vchans = devm_kcalloc (& pdev -> dev , SUN4I_DMA_NR_MAX_VCHANS ,
1203
1254
sizeof (struct sun4i_dma_vchan ), GFP_KERNEL );
1204
- if (!priv -> vchans || !priv -> pchans )
1255
+ priv -> pchans_used = devm_kcalloc (& pdev -> dev ,
1256
+ BITS_TO_LONGS (priv -> cfg -> dma_nr_max_channels ),
1257
+ sizeof (unsigned long ), GFP_KERNEL );
1258
+ if (!priv -> vchans || !priv -> pchans || !priv -> pchans_used )
1205
1259
return - ENOMEM ;
1206
1260
1207
1261
/*
1208
- * [0..SUN4I_NDMA_NR_MAX_CHANNELS ) are normal pchans, and
1209
- * [SUN4I_NDMA_NR_MAX_CHANNELS..SUN4I_DMA_NR_MAX_CHANNELS ) are
1262
+ * [0..priv->cfg->ndma_nr_max_channels ) are normal pchans, and
1263
+ * [priv->cfg->ndma_nr_max_channels..priv->cfg->dma_nr_max_channels ) are
1210
1264
* dedicated ones
1211
1265
*/
1212
- for (i = 0 ; i < SUN4I_NDMA_NR_MAX_CHANNELS ; i ++ )
1266
+ for (i = 0 ; i < priv -> cfg -> ndma_nr_max_channels ; i ++ )
1213
1267
priv -> pchans [i ].base = priv -> base +
1214
1268
SUN4I_NDMA_CHANNEL_REG_BASE (i );
1215
1269
1216
- for (j = 0 ; i < SUN4I_DMA_NR_MAX_CHANNELS ; i ++ , j ++ ) {
1270
+ for (j = 0 ; i < priv -> cfg -> dma_nr_max_channels ; i ++ , j ++ ) {
1217
1271
priv -> pchans [i ].base = priv -> base +
1218
1272
SUN4I_DDMA_CHANNEL_REG_BASE (j );
1219
1273
priv -> pchans [i ].is_dedicated = 1 ;
@@ -1284,8 +1338,27 @@ static void sun4i_dma_remove(struct platform_device *pdev)
1284
1338
clk_disable_unprepare (priv -> clk );
1285
1339
}
1286
1340
1341
+ static struct sun4i_dma_config sun4i_a10_dma_cfg = {
1342
+ .ndma_nr_max_channels = SUN4I_NDMA_NR_MAX_CHANNELS ,
1343
+ .ndma_nr_max_vchans = SUN4I_NDMA_NR_MAX_VCHANS ,
1344
+
1345
+ .ddma_nr_max_channels = SUN4I_DDMA_NR_MAX_CHANNELS ,
1346
+ .ddma_nr_max_vchans = SUN4I_DDMA_NR_MAX_VCHANS ,
1347
+
1348
+ .dma_nr_max_channels = SUN4I_DMA_NR_MAX_CHANNELS ,
1349
+
1350
+ .set_dst_data_width = set_dst_data_width_a10 ,
1351
+ .set_src_data_width = set_src_data_width_a10 ,
1352
+ .convert_burst = convert_burst_a10 ,
1353
+
1354
+ .ndma_drq_sdram = SUN4I_NDMA_DRQ_TYPE_SDRAM ,
1355
+ .ddma_drq_sdram = SUN4I_DDMA_DRQ_TYPE_SDRAM ,
1356
+
1357
+ .max_burst = SUN4I_MAX_BURST ,
1358
+ };
1359
+
1287
1360
static const struct of_device_id sun4i_dma_match [] = {
1288
- { .compatible = "allwinner,sun4i-a10-dma" },
1361
+ { .compatible = "allwinner,sun4i-a10-dma" , . data = & sun4i_a10_dma_cfg },
1289
1362
{ /* sentinel */ },
1290
1363
};
1291
1364
MODULE_DEVICE_TABLE (of , sun4i_dma_match );
0 commit comments