9090
9191#define DMA_CHAN_CUR_PARA 0x1c
9292
93+ /*
94+ * LLI address mangling
95+ *
96+ * The LLI link physical address is also mangled, but we avoid dealing
97+ * with that by allocating LLIs from the DMA32 zone.
98+ */
99+ #define SRC_HIGH_ADDR (x ) (((x) & 0x3U) << 16)
100+ #define DST_HIGH_ADDR (x ) (((x) & 0x3U) << 18)
93101
94102/*
95103 * Various hardware related defines
@@ -132,6 +140,7 @@ struct sun6i_dma_config {
132140 u32 dst_burst_lengths ;
133141 u32 src_addr_widths ;
134142 u32 dst_addr_widths ;
143+ bool has_high_addr ;
135144 bool has_mbus_clk ;
136145};
137146
@@ -623,6 +632,18 @@ static int set_config(struct sun6i_dma_dev *sdev,
623632 return 0 ;
624633}
625634
635+ static inline void sun6i_dma_set_addr (struct sun6i_dma_dev * sdev ,
636+ struct sun6i_dma_lli * v_lli ,
637+ dma_addr_t src , dma_addr_t dst )
638+ {
639+ v_lli -> src = lower_32_bits (src );
640+ v_lli -> dst = lower_32_bits (dst );
641+
642+ if (sdev -> cfg -> has_high_addr )
643+ v_lli -> para |= SRC_HIGH_ADDR (upper_32_bits (src )) |
644+ DST_HIGH_ADDR (upper_32_bits (dst ));
645+ }
646+
626647static struct dma_async_tx_descriptor * sun6i_dma_prep_dma_memcpy (
627648 struct dma_chan * chan , dma_addr_t dest , dma_addr_t src ,
628649 size_t len , unsigned long flags )
@@ -645,16 +666,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
645666 if (!txd )
646667 return NULL ;
647668
648- v_lli = dma_pool_alloc (sdev -> pool , GFP_NOWAIT , & p_lli );
669+ v_lli = dma_pool_alloc (sdev -> pool , GFP_DMA32 | GFP_NOWAIT , & p_lli );
649670 if (!v_lli ) {
650671 dev_err (sdev -> slave .dev , "Failed to alloc lli memory\n" );
651672 goto err_txd_free ;
652673 }
653674
654- v_lli -> src = src ;
655- v_lli -> dst = dest ;
656675 v_lli -> len = len ;
657676 v_lli -> para = NORMAL_WAIT ;
677+ sun6i_dma_set_addr (sdev , v_lli , src , dest );
658678
659679 burst = convert_burst (8 );
660680 width = convert_buswidth (DMA_SLAVE_BUSWIDTH_4_BYTES );
@@ -705,16 +725,17 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
705725 return NULL ;
706726
707727 for_each_sg (sgl , sg , sg_len , i ) {
708- v_lli = dma_pool_alloc (sdev -> pool , GFP_NOWAIT , & p_lli );
728+ v_lli = dma_pool_alloc (sdev -> pool , GFP_DMA32 | GFP_NOWAIT , & p_lli );
709729 if (!v_lli )
710730 goto err_lli_free ;
711731
712732 v_lli -> len = sg_dma_len (sg );
713733 v_lli -> para = NORMAL_WAIT ;
714734
715735 if (dir == DMA_MEM_TO_DEV ) {
716- v_lli -> src = sg_dma_address (sg );
717- v_lli -> dst = sconfig -> dst_addr ;
736+ sun6i_dma_set_addr (sdev , v_lli ,
737+ sg_dma_address (sg ),
738+ sconfig -> dst_addr );
718739 v_lli -> cfg = lli_cfg ;
719740 sdev -> cfg -> set_drq (& v_lli -> cfg , DRQ_SDRAM , vchan -> port );
720741 sdev -> cfg -> set_mode (& v_lli -> cfg , LINEAR_MODE , IO_MODE );
@@ -726,8 +747,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
726747 sg_dma_len (sg ), flags );
727748
728749 } else {
729- v_lli -> src = sconfig -> src_addr ;
730- v_lli -> dst = sg_dma_address (sg );
750+ sun6i_dma_set_addr (sdev , v_lli ,
751+ sconfig -> src_addr ,
752+ sg_dma_address (sg ));
731753 v_lli -> cfg = lli_cfg ;
732754 sdev -> cfg -> set_drq (& v_lli -> cfg , vchan -> port , DRQ_SDRAM );
733755 sdev -> cfg -> set_mode (& v_lli -> cfg , IO_MODE , LINEAR_MODE );
@@ -786,7 +808,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
786808 return NULL ;
787809
788810 for (i = 0 ; i < periods ; i ++ ) {
789- v_lli = dma_pool_alloc (sdev -> pool , GFP_NOWAIT , & p_lli );
811+ v_lli = dma_pool_alloc (sdev -> pool , GFP_DMA32 | GFP_NOWAIT , & p_lli );
790812 if (!v_lli ) {
791813 dev_err (sdev -> slave .dev , "Failed to alloc lli memory\n" );
792814 goto err_lli_free ;
@@ -796,14 +818,16 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
796818 v_lli -> para = NORMAL_WAIT ;
797819
798820 if (dir == DMA_MEM_TO_DEV ) {
799- v_lli -> src = buf_addr + period_len * i ;
800- v_lli -> dst = sconfig -> dst_addr ;
821+ sun6i_dma_set_addr (sdev , v_lli ,
822+ buf_addr + period_len * i ,
823+ sconfig -> dst_addr );
801824 v_lli -> cfg = lli_cfg ;
802825 sdev -> cfg -> set_drq (& v_lli -> cfg , DRQ_SDRAM , vchan -> port );
803826 sdev -> cfg -> set_mode (& v_lli -> cfg , LINEAR_MODE , IO_MODE );
804827 } else {
805- v_lli -> src = sconfig -> src_addr ;
806- v_lli -> dst = buf_addr + period_len * i ;
828+ sun6i_dma_set_addr (sdev , v_lli ,
829+ sconfig -> src_addr ,
830+ buf_addr + period_len * i );
807831 v_lli -> cfg = lli_cfg ;
808832 sdev -> cfg -> set_drq (& v_lli -> cfg , vchan -> port , DRQ_SDRAM );
809833 sdev -> cfg -> set_mode (& v_lli -> cfg , IO_MODE , LINEAR_MODE );
@@ -1174,8 +1198,6 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
11741198};
11751199
11761200/*
1177- * TODO: Add support for more than 4g physical addressing.
1178- *
11791201 * The A100 binding uses the number of dma channels from the
11801202 * device tree node.
11811203 */
@@ -1194,6 +1216,7 @@ static struct sun6i_dma_config sun50i_a100_dma_cfg = {
11941216 BIT (DMA_SLAVE_BUSWIDTH_2_BYTES ) |
11951217 BIT (DMA_SLAVE_BUSWIDTH_4_BYTES ) |
11961218 BIT (DMA_SLAVE_BUSWIDTH_8_BYTES ),
1219+ .has_high_addr = true,
11971220 .has_mbus_clk = true,
11981221};
11991222
0 commit comments