Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 113119
b: refs/heads/master
c: a21cff3
h: refs/heads/master
i:
  113117: 12955d6
  113115: 16d5719
  113111: fe4083e
  113103: 866acb2
  113087: ba797fa
v: v3
  • Loading branch information
David S. Miller committed Sep 11, 2008
1 parent 9e408f6 commit 701b5a0
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 121 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 22fecbae4446ad470b9237ee9b79f80f343b3838
refs/heads/master: a21cff3e5e39c087b5a4c5efb20f1744475c556e
2 changes: 1 addition & 1 deletion trunk/arch/sparc64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ obj-y := process.o setup.o cpu.o idprom.o reboot.o \

obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PCI) += pci.o pci_common.o \
obj-$(CONFIG_PCI) += pci.o pci_common.o psycho_common.o \
pci_psycho.o pci_sabre.o pci_schizo.o \
pci_sun4v.o pci_sun4v_asm.o pci_fire.o
obj-$(CONFIG_PCI_MSI) += pci_msi.o
Expand Down
65 changes: 7 additions & 58 deletions trunk/arch/sparc64/kernel/pci_psycho.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "pci_impl.h"
#include "iommu_common.h"
#include "psycho_common.h"

#define DRIVER_NAME "psycho"
#define PFX DRIVER_NAME ": "
Expand Down Expand Up @@ -787,63 +788,6 @@ static void __init psycho_scan_bus(struct pci_pbm_info *pbm,
psycho_register_error_handlers(pbm);
}

static int psycho_iommu_init(struct pci_pbm_info *pbm)
{
struct iommu *iommu = pbm->iommu;
unsigned long i;
u64 control;
int err;

/* Register addresses. */
iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL;
iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE;
iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH;
iommu->iommu_tags = iommu->iommu_flush + (0xa580UL - 0x0210UL);

/* PSYCHO's IOMMU lacks ctx flushing. */
iommu->iommu_ctxflush = 0;

/* We use the main control register of PSYCHO as the write
* completion register.
*/
iommu->write_complete_reg = pbm->controller_regs + PSYCHO_CONTROL;

/*
* Invalidate TLB Entries.
*/
control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL);
control |= PSYCHO_IOMMU_CTRL_DENAB;
psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control);
for (i = 0; i < 16; i++) {
psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0);
psycho_write(pbm->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0);
}

/* Leave diag mode enabled for full-flushing done
* in pci_iommu.c
*/
err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff,
pbm->numa_node);
if (err) {
printk(KERN_ERR PFX "iommu_table_init() fails\n");
return err;
}

psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE,
__pa(iommu->page_table));

control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL);
control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB);
psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control);

/* If necessary, hook us up for starfire IRQ translations. */
if (this_is_starfire)
starfire_hookup(pbm->portid);

return 0;
}

#define PSYCHO_IRQ_RETRY 0x1a00UL
#define PSYCHO_PCIA_DIAG 0x2020UL
#define PSYCHO_PCIB_DIAG 0x4020UL
Expand Down Expand Up @@ -1053,9 +997,14 @@ static int __devinit psycho_probe(struct of_device *op,

psycho_controller_hwinit(pbm);
if (!pbm->sibling) {
err = psycho_iommu_init(pbm);
err = psycho_iommu_init(pbm, 128, 0xc0000000,
0xffffffff, PSYCHO_CONTROL);
if (err)
goto out_free_iommu;

/* If necessary, hook us up for starfire IRQ translations. */
if (this_is_starfire)
starfire_hookup(pbm->portid);
}

psycho_pbm_init(pbm, op, is_pbm_a);
Expand Down
63 changes: 2 additions & 61 deletions trunk/arch/sparc64/kernel/pci_sabre.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "pci_impl.h"
#include "iommu_common.h"
#include "psycho_common.h"

#define DRIVER_NAME "sabre"
#define PFX DRIVER_NAME ": "
Expand Down Expand Up @@ -674,66 +675,6 @@ static void __init sabre_scan_bus(struct pci_pbm_info *pbm,
sabre_register_error_handlers(pbm);
}

static int sabre_iommu_init(struct pci_pbm_info *pbm,
int tsbsize, unsigned long dvma_offset,
u32 dma_mask)
{
struct iommu *iommu = pbm->iommu;
unsigned long i;
u64 control;
int err;

/* Register addresses. */
iommu->iommu_control = pbm->controller_regs + SABRE_IOMMU_CONTROL;
iommu->iommu_tsbbase = pbm->controller_regs + SABRE_IOMMU_TSBBASE;
iommu->iommu_flush = pbm->controller_regs + SABRE_IOMMU_FLUSH;
iommu->iommu_tags = iommu->iommu_flush + (0xa580UL - 0x0210UL);
iommu->write_complete_reg = pbm->controller_regs + SABRE_WRSYNC;
/* Sabre's IOMMU lacks ctx flushing. */
iommu->iommu_ctxflush = 0;

/* Invalidate TLB Entries. */
control = sabre_read(pbm->controller_regs + SABRE_IOMMU_CONTROL);
control |= SABRE_IOMMUCTRL_DENAB;
sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control);

for(i = 0; i < 16; i++) {
sabre_write(pbm->controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0);
sabre_write(pbm->controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0);
}

/* Leave diag mode enabled for full-flushing done
* in pci_iommu.c
*/
err = iommu_table_init(iommu, tsbsize * 1024 * 8,
dvma_offset, dma_mask, pbm->numa_node);
if (err) {
printk(KERN_ERR PFX "iommu_table_init() failed\n");
return err;
}

sabre_write(pbm->controller_regs + SABRE_IOMMU_TSBBASE,
__pa(iommu->page_table));

control = sabre_read(pbm->controller_regs + SABRE_IOMMU_CONTROL);
control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
control |= SABRE_IOMMUCTRL_ENAB;
switch(tsbsize) {
case 64:
control |= SABRE_IOMMU_TSBSZ_64K;
break;
case 128:
control |= SABRE_IOMMU_TSBSZ_128K;
break;
default:
printk(KERN_ERR PFX "Illegal TSB size %d\n", tsbsize);
return -EINVAL;
}
sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control);

return 0;
}

static void __init sabre_pbm_init(struct pci_pbm_info *pbm,
struct of_device *op)
{
Expand Down Expand Up @@ -862,7 +803,7 @@ static int __devinit sabre_probe(struct of_device *op,
goto out_free_iommu;
}

err = sabre_iommu_init(pbm, tsbsize, vdma[0], dma_mask);
err = psycho_iommu_init(pbm, tsbsize, vdma[0], dma_mask, SABRE_WRSYNC);
if (err)
goto out_free_iommu;

Expand Down
93 changes: 93 additions & 0 deletions trunk/arch/sparc64/kernel/psycho_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* psycho_common.c: Code common to PSYCHO and derivative PCI controllers.
*
* Copyright (C) 2008 David S. Miller <davem@davemloft.net>
*/
#include <linux/kernel.h>

#include <asm/upa.h>

#include "pci_impl.h"
#include "psycho_common.h"

#define PSYCHO_IOMMU_TAG 0xa580UL
#define PSYCHO_IOMMU_DATA 0xa600UL

static void psycho_iommu_flush(struct pci_pbm_info *pbm)
{
int i;

for (i = 0; i < 16; i++) {
unsigned long off = i * 8;

upa_writeq(0, pbm->controller_regs + PSYCHO_IOMMU_TAG + off);
upa_writeq(0, pbm->controller_regs + PSYCHO_IOMMU_DATA + off);
}
}

#define PSYCHO_IOMMU_CONTROL 0x0200UL
#define PSYCHO_IOMMU_CTRL_TSBSZ 0x0000000000070000UL
#define PSYCHO_IOMMU_TSBSZ_1K 0x0000000000000000UL
#define PSYCHO_IOMMU_TSBSZ_2K 0x0000000000010000UL
#define PSYCHO_IOMMU_TSBSZ_4K 0x0000000000020000UL
#define PSYCHO_IOMMU_TSBSZ_8K 0x0000000000030000UL
#define PSYCHO_IOMMU_TSBSZ_16K 0x0000000000040000UL
#define PSYCHO_IOMMU_TSBSZ_32K 0x0000000000050000UL
#define PSYCHO_IOMMU_TSBSZ_64K 0x0000000000060000UL
#define PSYCHO_IOMMU_TSBSZ_128K 0x0000000000070000UL
#define PSYCHO_IOMMU_CTRL_TBWSZ 0x0000000000000004UL
#define PSYCHO_IOMMU_CTRL_DENAB 0x0000000000000002UL
#define PSYCHO_IOMMU_CTRL_ENAB 0x0000000000000001UL
#define PSYCHO_IOMMU_FLUSH 0x0210UL
#define PSYCHO_IOMMU_TSBBASE 0x0208UL

int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
u32 dvma_offset, u32 dma_mask,
unsigned long write_complete_offset)
{
struct iommu *iommu = pbm->iommu;
u64 control;
int err;

iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL;
iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE;
iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH;
iommu->iommu_tags = pbm->controller_regs + PSYCHO_IOMMU_TAG;
iommu->write_complete_reg = (pbm->controller_regs +
write_complete_offset);

iommu->iommu_ctxflush = 0;

control = upa_readq(iommu->iommu_control);
control |= PSYCHO_IOMMU_CTRL_DENAB;
upa_writeq(control, iommu->iommu_control);

psycho_iommu_flush(pbm);

/* Leave diag mode enabled for full-flushing done in pci_iommu.c */
err = iommu_table_init(iommu, tsbsize * 1024 * 8,
dvma_offset, dma_mask, pbm->numa_node);
if (err)
return err;

upa_writeq(__pa(iommu->page_table), iommu->iommu_tsbbase);

control = upa_readq(iommu->iommu_control);
control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
control |= PSYCHO_IOMMU_CTRL_ENAB;

switch (tsbsize) {
case 64:
control |= PSYCHO_IOMMU_TSBSZ_64K;
break;
case 128:
control |= PSYCHO_IOMMU_TSBSZ_128K;
break;
default:
return -EINVAL;
}

upa_writeq(control, iommu->iommu_control);

return 0;

}
8 changes: 8 additions & 0 deletions trunk/arch/sparc64/kernel/psycho_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _PSYCHO_COMMON_H
#define _PSYCHO_COMMON_H

extern int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
u32 dvma_offset, u32 dma_mask,
unsigned long write_complete_offset);

#endif /* _PSYCHO_COMMON_H */

0 comments on commit 701b5a0

Please sign in to comment.