aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2007-10-10 05:42:55 -0400
committerBryan Wu <bryan.wu@analog.com>2007-10-10 05:42:55 -0400
commit1a7d91d651f25005c4f507aebf9eab17e508889c (patch)
treed3070fe9edd252e485a07fb41c5ee8a4df4cec5c
parenta359cca71e73a83612b5bbecea41d3b7a47160ca (diff)
Blackfin arch: flush/inv the correct range when using write back cache and fix bugs find by dmacopy
- flush/inv the correct range - dmacopy test failed when policy is write_back - invalidate before dma http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3367 It's the cache invalidate what is causing the issue. There is no invalidate only instruction it's always: FLUSHINV So when we "invalidate" after the DMA we might (do) overwrite freshly dma'ed data by dirty Cache WB content. Fixed by moving the "invalidate" at the beginning of dma_memcpy. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 17edd6599959..e19164fb4cd1 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -436,6 +436,10 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
436 blackfin_dcache_flush_range((unsigned int)src, 436 blackfin_dcache_flush_range((unsigned int)src,
437 (unsigned int)(src + size)); 437 (unsigned int)(src + size));
438 438
439 if ((unsigned long)dest < memory_end)
440 blackfin_dcache_invalidate_range((unsigned int)dest,
441 (unsigned int)(dest + size));
442
439 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 443 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
440 444
441 if ((unsigned long)src < (unsigned long)dest) 445 if ((unsigned long)src < (unsigned long)dest)
@@ -543,6 +547,8 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
543 } 547 }
544 } 548 }
545 549
550 SSYNC();
551
546 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) 552 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
547 ; 553 ;
548 554
@@ -552,9 +558,6 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
552 bfin_write_MDMA_S0_CONFIG(0); 558 bfin_write_MDMA_S0_CONFIG(0);
553 bfin_write_MDMA_D0_CONFIG(0); 559 bfin_write_MDMA_D0_CONFIG(0);
554 560
555 if ((unsigned long)dest < memory_end)
556 blackfin_dcache_invalidate_range((unsigned int)dest,
557 (unsigned int)(dest + size));
558 local_irq_restore(flags); 561 local_irq_restore(flags);
559 562
560 return dest; 563 return dest;
@@ -589,7 +592,8 @@ void dma_outsb(unsigned long addr, const void *buf, unsigned short len)
589 592
590 local_irq_save(flags); 593 local_irq_save(flags);
591 594
592 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len); 595 blackfin_dcache_flush_range((unsigned int)buf,
596 (unsigned int)(buf) + len);
593 597
594 bfin_write_MDMA_D0_START_ADDR(addr); 598 bfin_write_MDMA_D0_START_ADDR(addr);
595 bfin_write_MDMA_D0_X_COUNT(len); 599 bfin_write_MDMA_D0_X_COUNT(len);
@@ -604,6 +608,8 @@ void dma_outsb(unsigned long addr, const void *buf, unsigned short len)
604 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); 608 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
605 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); 609 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
606 610
611 SSYNC();
612
607 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 613 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
608 614
609 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 615 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -620,6 +626,9 @@ void dma_insb(unsigned long addr, void *buf, unsigned short len)
620{ 626{
621 unsigned long flags; 627 unsigned long flags;
622 628
629 blackfin_dcache_invalidate_range((unsigned int)buf,
630 (unsigned int)(buf) + len);
631
623 local_irq_save(flags); 632 local_irq_save(flags);
624 bfin_write_MDMA_D0_START_ADDR(buf); 633 bfin_write_MDMA_D0_START_ADDR(buf);
625 bfin_write_MDMA_D0_X_COUNT(len); 634 bfin_write_MDMA_D0_X_COUNT(len);
@@ -634,7 +643,7 @@ void dma_insb(unsigned long addr, void *buf, unsigned short len)
634 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); 643 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
635 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); 644 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
636 645
637 blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len); 646 SSYNC();
638 647
639 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 648 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
640 649
@@ -653,7 +662,8 @@ void dma_outsw(unsigned long addr, const void *buf, unsigned short len)
653 662
654 local_irq_save(flags); 663 local_irq_save(flags);
655 664
656 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len); 665 blackfin_dcache_flush_range((unsigned int)buf,
666 (unsigned int)(buf) + len * sizeof(short));
657 667
658 bfin_write_MDMA_D0_START_ADDR(addr); 668 bfin_write_MDMA_D0_START_ADDR(addr);
659 bfin_write_MDMA_D0_X_COUNT(len); 669 bfin_write_MDMA_D0_X_COUNT(len);
@@ -668,6 +678,8 @@ void dma_outsw(unsigned long addr, const void *buf, unsigned short len)
668 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); 678 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
669 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); 679 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
670 680
681 SSYNC();
682
671 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 683 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
672 684
673 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 685 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -683,6 +695,9 @@ void dma_insw(unsigned long addr, void *buf, unsigned short len)
683{ 695{
684 unsigned long flags; 696 unsigned long flags;
685 697
698 blackfin_dcache_invalidate_range((unsigned int)buf,
699 (unsigned int)(buf) + len * sizeof(short));
700
686 local_irq_save(flags); 701 local_irq_save(flags);
687 702
688 bfin_write_MDMA_D0_START_ADDR(buf); 703 bfin_write_MDMA_D0_START_ADDR(buf);
@@ -698,7 +713,7 @@ void dma_insw(unsigned long addr, void *buf, unsigned short len)
698 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); 713 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
699 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); 714 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
700 715
701 blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len); 716 SSYNC();
702 717
703 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 718 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
704 719
@@ -717,7 +732,8 @@ void dma_outsl(unsigned long addr, const void *buf, unsigned short len)
717 732
718 local_irq_save(flags); 733 local_irq_save(flags);
719 734
720 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len); 735 blackfin_dcache_flush_range((unsigned int)buf,
736 (unsigned int)(buf) + len * sizeof(long));
721 737
722 bfin_write_MDMA_D0_START_ADDR(addr); 738 bfin_write_MDMA_D0_START_ADDR(addr);
723 bfin_write_MDMA_D0_X_COUNT(len); 739 bfin_write_MDMA_D0_X_COUNT(len);
@@ -732,6 +748,8 @@ void dma_outsl(unsigned long addr, const void *buf, unsigned short len)
732 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); 748 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
733 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); 749 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
734 750
751 SSYNC();
752
735 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 753 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
736 754
737 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 755 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -747,6 +765,9 @@ void dma_insl(unsigned long addr, void *buf, unsigned short len)
747{ 765{
748 unsigned long flags; 766 unsigned long flags;
749 767
768 blackfin_dcache_invalidate_range((unsigned int)buf,
769 (unsigned int)(buf) + len * sizeof(long));
770
750 local_irq_save(flags); 771 local_irq_save(flags);
751 772
752 bfin_write_MDMA_D0_START_ADDR(buf); 773 bfin_write_MDMA_D0_START_ADDR(buf);
@@ -762,7 +783,7 @@ void dma_insl(unsigned long addr, void *buf, unsigned short len)
762 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); 783 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
763 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); 784 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
764 785
765 blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len); 786 SSYNC();
766 787
767 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 788 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
768 789