1313#include <linux/interrupt.h>
1414#include <linux/module.h>
1515#include <linux/of_dma.h>
16+ #include <linux/of_device.h>
1617#include <linux/platform_device.h>
1718#include <linux/slab.h>
1819#include <linux/spinlock.h>
3132#define SUN4I_DMA_CFG_SRC_ADDR_MODE (mode ) ((mode) << 5)
3233#define SUN4I_DMA_CFG_SRC_DRQ_TYPE (type ) (type)
3334
35+ #define SUN4I_MAX_BURST 8
36+
3437/** Normal DMA register values **/
3538
3639/* Normal DMA source/destination data request type values */
132135#define SUN4I_DDMA_MAX_SEG_SIZE SZ_16M
133136#define SUN4I_DMA_MAX_SEG_SIZE SUN4I_NDMA_MAX_SEG_SIZE
134137
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+
135164struct sun4i_dma_pchan {
136165 /* Register base of channel */
137166 void __iomem * base ;
@@ -170,14 +199,15 @@ struct sun4i_dma_contract {
170199};
171200
172201struct sun4i_dma_dev {
173- DECLARE_BITMAP ( pchans_used , SUN4I_DMA_NR_MAX_CHANNELS ) ;
202+ unsigned long * pchans_used ;
174203 struct dma_device slave ;
175204 struct sun4i_dma_pchan * pchans ;
176205 struct sun4i_dma_vchan * vchans ;
177206 void __iomem * base ;
178207 struct clk * clk ;
179208 int irq ;
180209 spinlock_t lock ;
210+ const struct sun4i_dma_config * cfg ;
181211};
182212
183213static struct sun4i_dma_dev * to_sun4i_dma_dev (struct dma_device * dev )
@@ -200,7 +230,17 @@ static struct device *chan2dev(struct dma_chan *chan)
200230 return & chan -> dev -> device ;
201231}
202232
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 )
204244{
205245 if (maxburst > 8 )
206246 return - EINVAL ;
@@ -233,15 +273,15 @@ static struct sun4i_dma_pchan *find_and_use_pchan(struct sun4i_dma_dev *priv,
233273 int i , max ;
234274
235275 /*
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
238278 */
239279 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 ;
242282 } else {
243283 i = 0 ;
244- max = SUN4I_NDMA_NR_MAX_CHANNELS ;
284+ max = priv -> cfg -> ndma_nr_max_channels ;
245285 }
246286
247287 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,
444484 size_t len , struct dma_slave_config * sconfig ,
445485 enum dma_transfer_direction direction )
446486{
487+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
447488 struct sun4i_dma_promise * promise ;
448489 int ret ;
449490
@@ -467,13 +508,13 @@ generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,
467508 sconfig -> src_addr_width , sconfig -> dst_addr_width );
468509
469510 /* Source burst */
470- ret = convert_burst (sconfig -> src_maxburst );
511+ ret = priv -> cfg -> convert_burst (sconfig -> src_maxburst );
471512 if (ret < 0 )
472513 goto fail ;
473514 promise -> cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH (ret );
474515
475516 /* Destination burst */
476- ret = convert_burst (sconfig -> dst_maxburst );
517+ ret = priv -> cfg -> convert_burst (sconfig -> dst_maxburst );
477518 if (ret < 0 )
478519 goto fail ;
479520 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,
482523 ret = convert_buswidth (sconfig -> src_addr_width );
483524 if (ret < 0 )
484525 goto fail ;
485- promise -> cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH ( ret );
526+ priv -> cfg -> set_src_data_width ( & promise -> cfg , ret );
486527
487528 /* Destination bus width */
488529 ret = convert_buswidth (sconfig -> dst_addr_width );
489530 if (ret < 0 )
490531 goto fail ;
491- promise -> cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH ( ret );
532+ priv -> cfg -> set_dst_data_width ( & promise -> cfg , ret );
492533
493534 return promise ;
494535
@@ -510,6 +551,7 @@ static struct sun4i_dma_promise *
510551generate_ddma_promise (struct dma_chan * chan , dma_addr_t src , dma_addr_t dest ,
511552 size_t len , struct dma_slave_config * sconfig )
512553{
554+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
513555 struct sun4i_dma_promise * promise ;
514556 int ret ;
515557
@@ -524,13 +566,13 @@ generate_ddma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,
524566 SUN4I_DDMA_CFG_BYTE_COUNT_MODE_REMAIN ;
525567
526568 /* Source burst */
527- ret = convert_burst (sconfig -> src_maxburst );
569+ ret = priv -> cfg -> convert_burst (sconfig -> src_maxburst );
528570 if (ret < 0 )
529571 goto fail ;
530572 promise -> cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH (ret );
531573
532574 /* Destination burst */
533- ret = convert_burst (sconfig -> dst_maxburst );
575+ ret = priv -> cfg -> convert_burst (sconfig -> dst_maxburst );
534576 if (ret < 0 )
535577 goto fail ;
536578 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,
539581 ret = convert_buswidth (sconfig -> src_addr_width );
540582 if (ret < 0 )
541583 goto fail ;
542- promise -> cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH ( ret );
584+ priv -> cfg -> set_src_data_width ( & promise -> cfg , ret );
543585
544586 /* Destination bus width */
545587 ret = convert_buswidth (sconfig -> dst_addr_width );
546588 if (ret < 0 )
547589 goto fail ;
548- promise -> cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH ( ret );
590+ priv -> cfg -> set_dst_data_width ( & promise -> cfg , ret );
549591
550592 return promise ;
551593
@@ -622,6 +664,7 @@ static struct dma_async_tx_descriptor *
622664sun4i_dma_prep_dma_memcpy (struct dma_chan * chan , dma_addr_t dest ,
623665 dma_addr_t src , size_t len , unsigned long flags )
624666{
667+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
625668 struct sun4i_dma_vchan * vchan = to_sun4i_dma_vchan (chan );
626669 struct dma_slave_config * sconfig = & vchan -> cfg ;
627670 struct sun4i_dma_promise * promise ;
@@ -638,8 +681,8 @@ sun4i_dma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest,
638681 */
639682 sconfig -> src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES ;
640683 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 ;
643686
644687 if (vchan -> is_dedicated )
645688 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,
654697
655698 /* Configure memcpy mode */
656699 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 );
659703 } 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 );
662707 }
663708
664709 /* 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,
673718 size_t period_len , enum dma_transfer_direction dir ,
674719 unsigned long flags )
675720{
721+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
676722 struct sun4i_dma_vchan * vchan = to_sun4i_dma_vchan (chan );
677723 struct dma_slave_config * sconfig = & vchan -> cfg ;
678724 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,
696742 if (vchan -> is_dedicated ) {
697743 io_mode = SUN4I_DDMA_ADDR_MODE_IO ;
698744 linear_mode = SUN4I_DDMA_ADDR_MODE_LINEAR ;
699- ram_type = SUN4I_DDMA_DRQ_TYPE_SDRAM ;
745+ ram_type = priv -> cfg -> ddma_drq_sdram ;
700746 } else {
701747 io_mode = SUN4I_NDMA_ADDR_MODE_IO ;
702748 linear_mode = SUN4I_NDMA_ADDR_MODE_LINEAR ;
703- ram_type = SUN4I_NDMA_DRQ_TYPE_SDRAM ;
749+ ram_type = priv -> cfg -> ndma_drq_sdram ;
704750 }
705751
706752 if (dir == DMA_MEM_TO_DEV ) {
@@ -793,6 +839,7 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
793839 unsigned int sg_len , enum dma_transfer_direction dir ,
794840 unsigned long flags , void * context )
795841{
842+ struct sun4i_dma_dev * priv = to_sun4i_dma_dev (chan -> device );
796843 struct sun4i_dma_vchan * vchan = to_sun4i_dma_vchan (chan );
797844 struct dma_slave_config * sconfig = & vchan -> cfg ;
798845 struct sun4i_dma_promise * promise ;
@@ -818,11 +865,11 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
818865 if (vchan -> is_dedicated ) {
819866 io_mode = SUN4I_DDMA_ADDR_MODE_IO ;
820867 linear_mode = SUN4I_DDMA_ADDR_MODE_LINEAR ;
821- ram_type = SUN4I_DDMA_DRQ_TYPE_SDRAM ;
868+ ram_type = priv -> cfg -> ddma_drq_sdram ;
822869 } else {
823870 io_mode = SUN4I_NDMA_ADDR_MODE_IO ;
824871 linear_mode = SUN4I_NDMA_ADDR_MODE_LINEAR ;
825- ram_type = SUN4I_NDMA_DRQ_TYPE_SDRAM ;
872+ ram_type = priv -> cfg -> ndma_drq_sdram ;
826873 }
827874
828875 if (dir == DMA_MEM_TO_DEV )
@@ -1150,6 +1197,10 @@ static int sun4i_dma_probe(struct platform_device *pdev)
11501197 if (!priv )
11511198 return - ENOMEM ;
11521199
1200+ priv -> cfg = of_device_get_match_data (& pdev -> dev );
1201+ if (!priv -> cfg )
1202+ return - ENODEV ;
1203+
11531204 priv -> base = devm_platform_ioremap_resource (pdev , 0 );
11541205 if (IS_ERR (priv -> base ))
11551206 return PTR_ERR (priv -> base );
@@ -1197,23 +1248,26 @@ static int sun4i_dma_probe(struct platform_device *pdev)
11971248
11981249 priv -> slave .dev = & pdev -> dev ;
11991250
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 ,
12011252 sizeof (struct sun4i_dma_pchan ), GFP_KERNEL );
12021253 priv -> vchans = devm_kcalloc (& pdev -> dev , SUN4I_DMA_NR_MAX_VCHANS ,
12031254 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 )
12051259 return - ENOMEM ;
12061260
12071261 /*
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
12101264 * dedicated ones
12111265 */
1212- for (i = 0 ; i < SUN4I_NDMA_NR_MAX_CHANNELS ; i ++ )
1266+ for (i = 0 ; i < priv -> cfg -> ndma_nr_max_channels ; i ++ )
12131267 priv -> pchans [i ].base = priv -> base +
12141268 SUN4I_NDMA_CHANNEL_REG_BASE (i );
12151269
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 ++ ) {
12171271 priv -> pchans [i ].base = priv -> base +
12181272 SUN4I_DDMA_CHANNEL_REG_BASE (j );
12191273 priv -> pchans [i ].is_dedicated = 1 ;
@@ -1284,8 +1338,27 @@ static void sun4i_dma_remove(struct platform_device *pdev)
12841338 clk_disable_unprepare (priv -> clk );
12851339}
12861340
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+
12871360static 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 },
12891362 { /* sentinel */ },
12901363};
12911364MODULE_DEVICE_TABLE (of , sun4i_dma_match );
0 commit comments