aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/pci_iommu.c167
-rw-r--r--arch/sparc64/kernel/sbus.c31
-rw-r--r--arch/sparc64/kernel/setup.c11
-rw-r--r--arch/sparc64/kernel/smp.c3
-rw-r--r--arch/sparc64/kernel/traps.c19
5 files changed, 123 insertions, 108 deletions
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 292983413ae2..33ca56c90da2 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -8,6 +8,7 @@
8#include <linux/kernel.h> 8#include <linux/kernel.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/delay.h>
11 12
12#include <asm/pbm.h> 13#include <asm/pbm.h>
13 14
@@ -379,6 +380,56 @@ bad:
379 return PCI_DMA_ERROR_CODE; 380 return PCI_DMA_ERROR_CODE;
380} 381}
381 382
383static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages)
384{
385 int limit;
386
387 PCI_STC_FLUSHFLAG_INIT(strbuf);
388 if (strbuf->strbuf_ctxflush &&
389 iommu->iommu_ctxflush) {
390 unsigned long matchreg, flushreg;
391
392 flushreg = strbuf->strbuf_ctxflush;
393 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
394
395 limit = 100000;
396 pci_iommu_write(flushreg, ctx);
397 for(;;) {
398 if (((long)pci_iommu_read(matchreg)) >= 0L)
399 break;
400 limit--;
401 if (!limit)
402 break;
403 udelay(1);
404 }
405 if (!limit)
406 printk(KERN_WARNING "pci_strbuf_flush: ctx flush "
407 "timeout vaddr[%08x] ctx[%lx]\n",
408 vaddr, ctx);
409 } else {
410 unsigned long i;
411
412 for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
413 pci_iommu_write(strbuf->strbuf_pflush, vaddr);
414 }
415
416 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
417 (void) pci_iommu_read(iommu->write_complete_reg);
418
419 limit = 100000;
420 while (!PCI_STC_FLUSHFLAG_SET(strbuf)) {
421 limit--;
422 if (!limit)
423 break;
424 udelay(1);
425 membar("#LoadLoad");
426 }
427 if (!limit)
428 printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
429 "vaddr[%08x] ctx[%lx] npages[%ld]\n",
430 vaddr, ctx, npages);
431}
432
382/* Unmap a single streaming mode DMA translation. */ 433/* Unmap a single streaming mode DMA translation. */
383void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) 434void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
384{ 435{
@@ -386,7 +437,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
386 struct pci_iommu *iommu; 437 struct pci_iommu *iommu;
387 struct pci_strbuf *strbuf; 438 struct pci_strbuf *strbuf;
388 iopte_t *base; 439 iopte_t *base;
389 unsigned long flags, npages, i, ctx; 440 unsigned long flags, npages, ctx;
390 441
391 if (direction == PCI_DMA_NONE) 442 if (direction == PCI_DMA_NONE)
392 BUG(); 443 BUG();
@@ -414,29 +465,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
414 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; 465 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
415 466
416 /* Step 1: Kick data out of streaming buffers if necessary. */ 467 /* Step 1: Kick data out of streaming buffers if necessary. */
417 if (strbuf->strbuf_enabled) { 468 if (strbuf->strbuf_enabled)
418 u32 vaddr = bus_addr; 469 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
419
420 PCI_STC_FLUSHFLAG_INIT(strbuf);
421 if (strbuf->strbuf_ctxflush &&
422 iommu->iommu_ctxflush) {
423 unsigned long matchreg, flushreg;
424
425 flushreg = strbuf->strbuf_ctxflush;
426 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
427 do {
428 pci_iommu_write(flushreg, ctx);
429 } while(((long)pci_iommu_read(matchreg)) < 0L);
430 } else {
431 for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
432 pci_iommu_write(strbuf->strbuf_pflush, vaddr);
433 }
434
435 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
436 (void) pci_iommu_read(iommu->write_complete_reg);
437 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
438 membar("#LoadLoad");
439 }
440 470
441 /* Step 2: Clear out first TSB entry. */ 471 /* Step 2: Clear out first TSB entry. */
442 iopte_make_dummy(iommu, base); 472 iopte_make_dummy(iommu, base);
@@ -647,29 +677,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
647 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; 677 ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
648 678
649 /* Step 1: Kick data out of streaming buffers if necessary. */ 679 /* Step 1: Kick data out of streaming buffers if necessary. */
650 if (strbuf->strbuf_enabled) { 680 if (strbuf->strbuf_enabled)
651 u32 vaddr = (u32) bus_addr; 681 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
652
653 PCI_STC_FLUSHFLAG_INIT(strbuf);
654 if (strbuf->strbuf_ctxflush &&
655 iommu->iommu_ctxflush) {
656 unsigned long matchreg, flushreg;
657
658 flushreg = strbuf->strbuf_ctxflush;
659 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
660 do {
661 pci_iommu_write(flushreg, ctx);
662 } while(((long)pci_iommu_read(matchreg)) < 0L);
663 } else {
664 for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
665 pci_iommu_write(strbuf->strbuf_pflush, vaddr);
666 }
667
668 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
669 (void) pci_iommu_read(iommu->write_complete_reg);
670 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
671 membar("#LoadLoad");
672 }
673 682
674 /* Step 2: Clear out first TSB entry. */ 683 /* Step 2: Clear out first TSB entry. */
675 iopte_make_dummy(iommu, base); 684 iopte_make_dummy(iommu, base);
@@ -715,28 +724,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
715 } 724 }
716 725
717 /* Step 2: Kick data out of streaming buffers. */ 726 /* Step 2: Kick data out of streaming buffers. */
718 PCI_STC_FLUSHFLAG_INIT(strbuf); 727 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
719 if (iommu->iommu_ctxflush &&
720 strbuf->strbuf_ctxflush) {
721 unsigned long matchreg, flushreg;
722
723 flushreg = strbuf->strbuf_ctxflush;
724 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
725 do {
726 pci_iommu_write(flushreg, ctx);
727 } while(((long)pci_iommu_read(matchreg)) < 0L);
728 } else {
729 unsigned long i;
730
731 for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
732 pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
733 }
734
735 /* Step 3: Perform flush synchronization sequence. */
736 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
737 (void) pci_iommu_read(iommu->write_complete_reg);
738 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
739 membar("#LoadLoad");
740 728
741 spin_unlock_irqrestore(&iommu->lock, flags); 729 spin_unlock_irqrestore(&iommu->lock, flags);
742} 730}
@@ -749,7 +737,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
749 struct pcidev_cookie *pcp; 737 struct pcidev_cookie *pcp;
750 struct pci_iommu *iommu; 738 struct pci_iommu *iommu;
751 struct pci_strbuf *strbuf; 739 struct pci_strbuf *strbuf;
752 unsigned long flags, ctx; 740 unsigned long flags, ctx, npages, i;
741 u32 bus_addr;
753 742
754 pcp = pdev->sysdata; 743 pcp = pdev->sysdata;
755 iommu = pcp->pbm->iommu; 744 iommu = pcp->pbm->iommu;
@@ -772,36 +761,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
772 } 761 }
773 762
774 /* Step 2: Kick data out of streaming buffers. */ 763 /* Step 2: Kick data out of streaming buffers. */
775 PCI_STC_FLUSHFLAG_INIT(strbuf); 764 bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
776 if (iommu->iommu_ctxflush && 765 for(i = 1; i < nelems; i++)
777 strbuf->strbuf_ctxflush) { 766 if (!sglist[i].dma_length)
778 unsigned long matchreg, flushreg; 767 break;
779 768 i--;
780 flushreg = strbuf->strbuf_ctxflush; 769 npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
781 matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); 770 - bus_addr) >> IO_PAGE_SHIFT;
782 do { 771 pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
783 pci_iommu_write(flushreg, ctx);
784 } while (((long)pci_iommu_read(matchreg)) < 0L);
785 } else {
786 unsigned long i, npages;
787 u32 bus_addr;
788
789 bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
790
791 for(i = 1; i < nelems; i++)
792 if (!sglist[i].dma_length)
793 break;
794 i--;
795 npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
796 for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
797 pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
798 }
799
800 /* Step 3: Perform flush synchronization sequence. */
801 pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
802 (void) pci_iommu_read(iommu->write_complete_reg);
803 while (!PCI_STC_FLUSHFLAG_SET(strbuf))
804 membar("#LoadLoad");
805 772
806 spin_unlock_irqrestore(&iommu->lock, flags); 773 spin_unlock_irqrestore(&iommu->lock, flags);
807} 774}
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 14d9c3a21b9a..76ea6455433f 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -117,19 +117,34 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages
117 117
118#define STRBUF_TAG_VALID 0x02UL 118#define STRBUF_TAG_VALID 0x02UL
119 119
120static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) 120static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
121{ 121{
122 unsigned long n;
123 int limit;
124
122 iommu->strbuf_flushflag = 0UL; 125 iommu->strbuf_flushflag = 0UL;
123 while (npages--) 126 n = npages;
124 upa_writeq(base + (npages << IO_PAGE_SHIFT), 127 while (n--)
128 upa_writeq(base + (n << IO_PAGE_SHIFT),
125 iommu->strbuf_regs + STRBUF_PFLUSH); 129 iommu->strbuf_regs + STRBUF_PFLUSH);
126 130
127 /* Whoopee cushion! */ 131 /* Whoopee cushion! */
128 upa_writeq(__pa(&iommu->strbuf_flushflag), 132 upa_writeq(__pa(&iommu->strbuf_flushflag),
129 iommu->strbuf_regs + STRBUF_FSYNC); 133 iommu->strbuf_regs + STRBUF_FSYNC);
130 upa_readq(iommu->sbus_control_reg); 134 upa_readq(iommu->sbus_control_reg);
131 while (iommu->strbuf_flushflag == 0UL) 135
136 limit = 100000;
137 while (iommu->strbuf_flushflag == 0UL) {
138 limit--;
139 if (!limit)
140 break;
141 udelay(1);
132 membar("#LoadLoad"); 142 membar("#LoadLoad");
143 }
144 if (!limit)
145 printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
146 "vaddr[%08x] npages[%ld]\n",
147 base, npages);
133} 148}
134 149
135static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) 150static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
@@ -406,7 +421,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size,
406 421
407 spin_lock_irqsave(&iommu->lock, flags); 422 spin_lock_irqsave(&iommu->lock, flags);
408 free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); 423 free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
409 strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); 424 sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
410 spin_unlock_irqrestore(&iommu->lock, flags); 425 spin_unlock_irqrestore(&iommu->lock, flags);
411} 426}
412 427
@@ -569,7 +584,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int
569 iommu = sdev->bus->iommu; 584 iommu = sdev->bus->iommu;
570 spin_lock_irqsave(&iommu->lock, flags); 585 spin_lock_irqsave(&iommu->lock, flags);
571 free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); 586 free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
572 strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); 587 sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
573 spin_unlock_irqrestore(&iommu->lock, flags); 588 spin_unlock_irqrestore(&iommu->lock, flags);
574} 589}
575 590
@@ -581,7 +596,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t
581 size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); 596 size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
582 597
583 spin_lock_irqsave(&iommu->lock, flags); 598 spin_lock_irqsave(&iommu->lock, flags);
584 strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); 599 sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
585 spin_unlock_irqrestore(&iommu->lock, flags); 600 spin_unlock_irqrestore(&iommu->lock, flags);
586} 601}
587 602
@@ -605,7 +620,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int
605 size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; 620 size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
606 621
607 spin_lock_irqsave(&iommu->lock, flags); 622 spin_lock_irqsave(&iommu->lock, flags);
608 strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); 623 sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
609 spin_unlock_irqrestore(&iommu->lock, flags); 624 spin_unlock_irqrestore(&iommu->lock, flags);
610} 625}
611 626
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 12c3d84b7460..b7e6a91952b2 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -383,6 +383,17 @@ static void __init process_switch(char c)
383 /* Use PROM debug console. */ 383 /* Use PROM debug console. */
384 register_console(&prom_debug_console); 384 register_console(&prom_debug_console);
385 break; 385 break;
386 case 'P':
387 /* Force UltraSPARC-III P-Cache on. */
388 if (tlb_type != cheetah) {
389 printk("BOOT: Ignoring P-Cache force option.\n");
390 break;
391 }
392 cheetah_pcache_forced_on = 1;
393 add_taint(TAINT_MACHINE_CHECK);
394 cheetah_enable_pcache();
395 break;
396
386 default: 397 default:
387 printk("Unknown boot switch (-%c)\n", c); 398 printk("Unknown boot switch (-%c)\n", c);
388 break; 399 break;
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 6dff06a44e76..e5b9c7a27789 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -123,6 +123,9 @@ void __init smp_callin(void)
123 123
124 smp_setup_percpu_timer(); 124 smp_setup_percpu_timer();
125 125
126 if (cheetah_pcache_forced_on)
127 cheetah_enable_pcache();
128
126 local_irq_enable(); 129 local_irq_enable();
127 130
128 calibrate_delay(); 131 calibrate_delay();
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 56b203a2af69..a9f4596d7c2b 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -421,6 +421,25 @@ asmlinkage void cee_log(unsigned long ce_status,
421 } 421 }
422} 422}
423 423
424int cheetah_pcache_forced_on;
425
426void cheetah_enable_pcache(void)
427{
428 unsigned long dcr;
429
430 printk("CHEETAH: Enabling P-Cache on cpu %d.\n",
431 smp_processor_id());
432
433 __asm__ __volatile__("ldxa [%%g0] %1, %0"
434 : "=r" (dcr)
435 : "i" (ASI_DCU_CONTROL_REG));
436 dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL);
437 __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
438 "membar #Sync"
439 : /* no outputs */
440 : "r" (dcr), "i" (ASI_DCU_CONTROL_REG));
441}
442
424/* Cheetah error trap handling. */ 443/* Cheetah error trap handling. */
425static unsigned long ecache_flush_physbase; 444static unsigned long ecache_flush_physbase;
426static unsigned long ecache_flush_linesize; 445static unsigned long ecache_flush_linesize;