aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@st.com>2011-08-05 06:02:37 -0400
committerVinod Koul <vinod.koul@intel.com>2011-08-25 10:03:38 -0400
commit16a2e7d359b9fc64fb8a6717c0642691b1e60bb7 (patch)
treebfeea21d5b565a39ff32718327eb993d9b29c4aa /drivers/dma
parent28da28365da3f3bea1d4b7212a8a40e4b9ac3229 (diff)
dmaengine/amba-pl08x: Get rid of pl08x_pre_boundary()
Pl080 Manual says: "Bursts do not cross the 1KB address boundary" We can program the controller to cross 1 KB boundary on a burst and controller can take care of this boundary condition by itself. Following is the discussion with ARM Technical Support Guys (David): [Viresh] Manual says: "Bursts do not cross the 1KB address boundary" What does that actually mean? As, Maximum size transferable with a single LLI is 4095 * 4 =16380 ~ 16KB. So, if we don't have src/dest address aligned to burst size, we can't use this big of an LLI. [David] There is a difference between bursts describing the total data transferred by the DMA controller and AHB bursts. Bursts described by the programmable parameters in the PL080 have no direct connection with the bursts that are seen on the AHB bus. The statement that "Bursts do not cross the 1KB address boundary" in the TRM is referring to AHB bursts, where this limitation is a requirement of the AHB spec. You can still issue bursts within the PL080 that are in excess of 1KB. The PL080 will make sure that its bursts are broken down into legal AHB bursts which will be formatted to ensure that no AHB burst crosses a 1KB boundary. Based on above discussion, this patch removes all code related to 1 KB boundary as we are not required to handle this in driver. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/amba-pl08x.c141
1 files changed, 17 insertions, 124 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 6bba32e5ddb8..be9a1c718f9a 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -149,14 +149,6 @@ struct pl08x_driver_data {
149 * PL08X specific defines 149 * PL08X specific defines
150 */ 150 */
151 151
152/*
153 * Memory boundaries: the manual for PL08x says that the controller
154 * cannot read past a 1KiB boundary, so these defines are used to
155 * create transfer LLIs that do not cross such boundaries.
156 */
157#define PL08X_BOUNDARY_SHIFT (10) /* 1KB 0x400 */
158#define PL08X_BOUNDARY_SIZE (1 << PL08X_BOUNDARY_SHIFT)
159
160/* Size (bytes) of each LLI buffer allocated for one transfer */ 152/* Size (bytes) of each LLI buffer allocated for one transfer */
161# define PL08X_LLI_TSFR_SIZE 0x2000 153# define PL08X_LLI_TSFR_SIZE 0x2000
162 154
@@ -568,18 +560,6 @@ static void pl08x_fill_lli_for_desc(struct pl08x_lli_build_data *bd,
568} 560}
569 561
570/* 562/*
571 * Return number of bytes to fill to boundary, or len.
572 * This calculation works for any value of addr.
573 */
574static inline size_t pl08x_pre_boundary(u32 addr, size_t len)
575{
576 size_t boundary_len = PL08X_BOUNDARY_SIZE -
577 (addr & (PL08X_BOUNDARY_SIZE - 1));
578
579 return min(boundary_len, len);
580}
581
582/*
583 * This fills in the table of LLIs for the transfer descriptor 563 * This fills in the table of LLIs for the transfer descriptor
584 * Note that we assume we never have to change the burst sizes 564 * Note that we assume we never have to change the burst sizes
585 * Return 0 for error 565 * Return 0 for error
@@ -685,118 +665,30 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
685 * width left 665 * width left
686 */ 666 */
687 while (bd.remainder > (mbus->buswidth - 1)) { 667 while (bd.remainder > (mbus->buswidth - 1)) {
688 size_t lli_len, target_len, tsize, odd_bytes; 668 size_t lli_len, tsize;
689 669
690 /* 670 /*
691 * If enough left try to send max possible, 671 * If enough left try to send max possible,
692 * otherwise try to send the remainder 672 * otherwise try to send the remainder
693 */ 673 */
694 target_len = min(bd.remainder, max_bytes_per_lli); 674 lli_len = min(bd.remainder, max_bytes_per_lli);
695
696 /* 675 /*
697 * Set bus lengths for incrementing buses to the 676 * Check against minimum bus alignment: Calculate actual
698 * number of bytes which fill to next memory boundary, 677 * transfer size in relation to bus width and get a
699 * limiting on the target length calculated above. 678 * maximum remainder of the smallest bus width - 1
700 */ 679 */
701 if (cctl & PL080_CONTROL_SRC_INCR) 680 tsize = lli_len / min(mbus->buswidth, sbus->buswidth);
702 bd.srcbus.fill_bytes = 681 lli_len = tsize * min(mbus->buswidth, sbus->buswidth);
703 pl08x_pre_boundary(bd.srcbus.addr,
704 target_len);
705 else
706 bd.srcbus.fill_bytes = target_len;
707
708 if (cctl & PL080_CONTROL_DST_INCR)
709 bd.dstbus.fill_bytes =
710 pl08x_pre_boundary(bd.dstbus.addr,
711 target_len);
712 else
713 bd.dstbus.fill_bytes = target_len;
714
715 /* Find the nearest */
716 lli_len = min(bd.srcbus.fill_bytes,
717 bd.dstbus.fill_bytes);
718
719 BUG_ON(lli_len > bd.remainder);
720
721 if (lli_len <= 0) {
722 dev_err(&pl08x->adev->dev,
723 "%s lli_len is %zu, <= 0\n",
724 __func__, lli_len);
725 return 0;
726 }
727
728 if (lli_len == target_len) {
729 /*
730 * Can send what we wanted.
731 * Maintain alignment
732 */
733 lli_len = (lli_len/mbus->buswidth) *
734 mbus->buswidth;
735 odd_bytes = 0;
736 } else {
737 /*
738 * So now we know how many bytes to transfer
739 * to get to the nearest boundary. The next
740 * LLI will past the boundary. However, we
741 * may be working to a boundary on the slave
742 * bus. We need to ensure the master stays
743 * aligned, and that we are working in
744 * multiples of the bus widths.
745 */
746 odd_bytes = lli_len % mbus->buswidth;
747 lli_len -= odd_bytes;
748
749 }
750
751 if (lli_len) {
752 /*
753 * Check against minimum bus alignment:
754 * Calculate actual transfer size in relation
755 * to bus width an get a maximum remainder of
756 * the smallest bus width - 1
757 */
758 /* FIXME: use round_down()? */
759 tsize = lli_len / min(mbus->buswidth,
760 sbus->buswidth);
761 lli_len = tsize * min(mbus->buswidth,
762 sbus->buswidth);
763
764 if (target_len != lli_len) {
765 dev_vdbg(&pl08x->adev->dev,
766 "%s can't send what we want. Desired 0x%08zx, lli of 0x%08zx bytes in txd of 0x%08zx\n",
767 __func__, target_len, lli_len, txd->len);
768 }
769
770 cctl = pl08x_cctl_bits(cctl,
771 bd.srcbus.buswidth,
772 bd.dstbus.buswidth,
773 tsize);
774
775 dev_vdbg(&pl08x->adev->dev,
776 "%s fill lli with single lli chunk of size 0x%08zx (remainder 0x%08zx)\n",
777 __func__, lli_len, bd.remainder);
778 pl08x_fill_lli_for_desc(&bd, num_llis++,
779 lli_len, cctl);
780 total_bytes += lli_len;
781 }
782 682
783 if (odd_bytes) { 683 dev_vdbg(&pl08x->adev->dev,
784 /* 684 "%s fill lli with single lli chunk of "
785 * Creep past the boundary, maintaining 685 "size 0x%08zx (remainder 0x%08zx)\n",
786 * master alignment 686 __func__, lli_len, bd.remainder);
787 */ 687
788 int j; 688 cctl = pl08x_cctl_bits(cctl, bd.srcbus.buswidth,
789 for (j = 0; (j < mbus->buswidth) 689 bd.dstbus.buswidth, tsize);
790 && (bd.remainder); j++) { 690 pl08x_fill_lli_for_desc(&bd, num_llis++, lli_len, cctl);
791 cctl = pl08x_cctl_bits(cctl, 1, 1, 1); 691 total_bytes += lli_len;
792 dev_vdbg(&pl08x->adev->dev,
793 "%s align with boundary, single byte (remain 0x%08zx)\n",
794 __func__, bd.remainder);
795 pl08x_fill_lli_for_desc(&bd,
796 num_llis++, 1, cctl);
797 total_bytes++;
798 }
799 }
800 } 692 }
801 693
802 /* 694 /*
@@ -811,6 +703,7 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
811 total_bytes++; 703 total_bytes++;
812 } 704 }
813 } 705 }
706
814 if (total_bytes != txd->len) { 707 if (total_bytes != txd->len) {
815 dev_err(&pl08x->adev->dev, 708 dev_err(&pl08x->adev->dev,
816 "%s size of encoded lli:s don't match total txd, transferred 0x%08zx from size 0x%08zx\n", 709 "%s size of encoded lli:s don't match total txd, transferred 0x%08zx from size 0x%08zx\n",