diff options
| -rw-r--r-- | drivers/dma/amba-pl08x.c | 141 | ||||
| -rw-r--r-- | include/linux/amba/pl08x.h | 2 |
2 files changed, 17 insertions, 126 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 6bba32e5ddb..be9a1c718f9 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 | */ | ||
| 574 | static 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", |
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h index cd8f629da58..ecd17f581e7 100644 --- a/include/linux/amba/pl08x.h +++ b/include/linux/amba/pl08x.h | |||
| @@ -77,13 +77,11 @@ struct pl08x_channel_data { | |||
| 77 | * @addr: current address | 77 | * @addr: current address |
| 78 | * @maxwidth: the maximum width of a transfer on this bus | 78 | * @maxwidth: the maximum width of a transfer on this bus |
| 79 | * @buswidth: the width of this bus in bytes: 1, 2 or 4 | 79 | * @buswidth: the width of this bus in bytes: 1, 2 or 4 |
| 80 | * @fill_bytes: bytes required to fill to the next bus memory boundary | ||
| 81 | */ | 80 | */ |
| 82 | struct pl08x_bus_data { | 81 | struct pl08x_bus_data { |
| 83 | dma_addr_t addr; | 82 | dma_addr_t addr; |
| 84 | u8 maxwidth; | 83 | u8 maxwidth; |
