pasemi_mac: enable iommu support
Enable IOMMU support for pasemi_mac, but avoid using it on non-partitioned
systems for performance reasons.
The user can override this by selecting the PPC_PASEMI_IOMMU_DMA_FORCE
configuration option.
Signed-off-by: Olof Johansson [EMAIL PROTECTED]
---
On Wed, Oct 03, 2007 at 01:47:17PM -0400, Jeff Garzik wrote:
You sent patch #10 against as patch #11 :)
Oops! Here's the real copy.
-Olof
Index: k.org/arch/powerpc/platforms/pasemi/iommu.c
===
--- k.org.orig/arch/powerpc/platforms/pasemi/iommu.c
+++ k.org/arch/powerpc/platforms/pasemi/iommu.c
@@ -25,6 +25,7 @@
#include asm/iommu.h
#include asm/machdep.h
#include asm/abs_addr.h
+#include asm/firmware.h
#define IOBMAP_PAGE_SHIFT 12
@@ -175,13 +176,17 @@ static void pci_dma_dev_setup_pasemi(str
{
pr_debug(pci_dma_dev_setup, dev %p (%s)\n, dev, pci_name(dev));
- /* DMA device is untranslated, but all other PCI-e goes through
-* the IOMMU
+#if !defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
+ /* For non-LPAR environment, don't translate anything for the DMA
+* engine. The exception to this is if the user has enabled
+* CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE at build time.
*/
- if (dev-vendor == 0x1959 dev-device == 0xa007)
+ if (dev-vendor == 0x1959 dev-device == 0xa007
+ !firmware_has_feature(FW_FEATURE_LPAR))
dev-dev.archdata.dma_ops = dma_direct_ops;
- else
- dev-dev.archdata.dma_data = iommu_table_iobmap;
+#endif
+
+ dev-dev.archdata.dma_data = iommu_table_iobmap;
}
static void pci_dma_bus_setup_null(struct pci_bus *b) { }
Index: k.org/drivers/net/pasemi_mac.c
===
--- k.org.orig/drivers/net/pasemi_mac.c
+++ k.org/drivers/net/pasemi_mac.c
@@ -34,6 +34,7 @@
#include net/checksum.h
#include asm/irq.h
+#include asm/firmware.h
#include pasemi_mac.h
@@ -89,6 +90,15 @@ MODULE_PARM_DESC(debug, PA Semi MAC bit
static struct pasdma_status *dma_status;
+static int translation_enabled(void)
+{
+#if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
+ return 1;
+#else
+ return firmware_has_feature(FW_FEATURE_LPAR);
+#endif
+}
+
static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val)
{
@@ -193,6 +203,7 @@ static int pasemi_mac_setup_rx_resources
struct pasemi_mac_rxring *ring;
struct pasemi_mac *mac = netdev_priv(dev);
int chan_id = mac-dma_rxch;
+ unsigned int cfg;
ring = kzalloc(sizeof(*ring), GFP_KERNEL);
@@ -232,20 +243,28 @@ static int pasemi_mac_setup_rx_resources
PAS_DMA_RXCHAN_BASEU_BRBH(ring-dma 32) |
PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE 3));
- write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
- PAS_DMA_RXCHAN_CFG_HBU(2));
+ cfg = PAS_DMA_RXCHAN_CFG_HBU(2);
+
+ if (translation_enabled())
+ cfg |= PAS_DMA_RXCHAN_CFG_CTR;
+
+ write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), cfg);
write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac-dma_if),
- PAS_DMA_RXINT_BASEL_BRBL(__pa(ring-buffers)));
+ PAS_DMA_RXINT_BASEL_BRBL(ring-buf_dma));
write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac-dma_if),
- PAS_DMA_RXINT_BASEU_BRBH(__pa(ring-buffers) 32) |
+ PAS_DMA_RXINT_BASEU_BRBH(ring-buf_dma 32) |
PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE 3));
- write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac-dma_if),
- PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 |
- PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP |
- PAS_DMA_RXINT_CFG_HEN);
+ cfg = PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 |
+ PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP |
+ PAS_DMA_RXINT_CFG_HEN;
+
+ if (translation_enabled())
+ cfg |= PAS_DMA_RXINT_CFG_ITRR | PAS_DMA_RXINT_CFG_ITR;
+
+ write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac-dma_if), cfg);
ring-next_to_fill = 0;
ring-next_to_clean = 0;
@@ -275,6 +294,7 @@ static int pasemi_mac_setup_tx_resources
u32 val;
int chan_id = mac-dma_txch;
struct pasemi_mac_txring *ring;
+ unsigned int cfg;
ring = kzalloc(sizeof(*ring), GFP_KERNEL);
if (!ring)
@@ -304,11 +324,15 @@ static int pasemi_mac_setup_tx_resources
write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val);
- write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id),
- PAS_DMA_TXCHAN_CFG_TY_IFACE |
- PAS_DMA_TXCHAN_CFG_TATTR(mac-dma_if) |
- PAS_DMA_TXCHAN_CFG_UP |
-