Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af289e80 authored by Olof Johansson's avatar Olof Johansson Committed by David S. Miller
Browse files

pasemi_mac: enable iommu support



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: default avatarOlof Johansson <olof@lixom.net>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 9ddf7774
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -18,6 +18,16 @@ config PPC_PASEMI_IOMMU
	help
	  IOMMU support for PA6T-1682M

config PPC_PASEMI_IOMMU_DMA_FORCE
	bool "Force DMA engine to use IOMMU"
	depends on PPC_PASEMI_IOMMU
	help
	  This option forces the use of the IOMMU also for the
	  DMA engine. Otherwise the kernel will use it only when
	  running under a hypervisor.

	  If in doubt, say "N".

config PPC_PASEMI_MDIO
	depends on PHYLIB
	tristate "MDIO support via GPIO"
+10 −5
Original line number Diff line number Diff line
@@ -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,12 +176,16 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
{
	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
#endif

	dev->dev.archdata.dma_data = &iommu_table_iobmap;
}

+37 −13
Original line number Diff line number Diff line
@@ -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 bitmapped debugging message enable value");

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 net_device *dev)
	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(struct net_device *dev)
			   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 |
	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);
	      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(struct net_device *dev)
	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(struct net_device *dev)

	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 |
	cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
	      PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
	      PAS_DMA_TXCHAN_CFG_UP |
			   PAS_DMA_TXCHAN_CFG_WT(2));
	      PAS_DMA_TXCHAN_CFG_WT(2);

	if (translation_enabled())
		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;

	write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), cfg);

	ring->next_to_fill = 0;
	ring->next_to_clean = 0;
+6 −2
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ enum {
#define    PAS_DMA_RXINT_CFG_DHL_S	24
#define    PAS_DMA_RXINT_CFG_DHL(x)	(((x) << PAS_DMA_RXINT_CFG_DHL_S) & \
					 PAS_DMA_RXINT_CFG_DHL_M)
#define    PAS_DMA_RXINT_CFG_ITR	0x00400000
#define    PAS_DMA_RXINT_CFG_LW		0x00200000
#define    PAS_DMA_RXINT_CFG_L2		0x00100000
#define    PAS_DMA_RXINT_CFG_HEN	0x00080000
@@ -258,9 +259,11 @@ enum {
#define    PAS_DMA_TXCHAN_CFG_WT_S	6
#define    PAS_DMA_TXCHAN_CFG_WT(x)	(((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
					 PAS_DMA_TXCHAN_CFG_WT_M)
#define    PAS_DMA_TXCHAN_CFG_CF	0x00001000	/* Clean first line */
#define    PAS_DMA_TXCHAN_CFG_CL	0x00002000	/* Clean last line */
#define    PAS_DMA_TXCHAN_CFG_TRD	0x00010000	/* translate data */
#define    PAS_DMA_TXCHAN_CFG_TRR	0x00008000	/* translate rings */
#define    PAS_DMA_TXCHAN_CFG_UP	0x00004000	/* update tx descr when sent */
#define    PAS_DMA_TXCHAN_CFG_CL	0x00002000	/* Clean last line */
#define    PAS_DMA_TXCHAN_CFG_CF	0x00001000	/* Clean first line */
#define PAS_DMA_TXCHAN_INCR(c)    (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_BASEL(c)   (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define    PAS_DMA_TXCHAN_BASEL_BRBL_M	0xffffffc0
@@ -294,6 +297,7 @@ enum {
#define    PAS_DMA_RXCHAN_CCMDSTA_FD	0x00001000
#define    PAS_DMA_RXCHAN_CCMDSTA_DT	0x00000800
#define PAS_DMA_RXCHAN_CFG(c)     (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE)
#define    PAS_DMA_RXCHAN_CFG_CTR	0x00000400
#define    PAS_DMA_RXCHAN_CFG_HBU_M	0x00000380
#define    PAS_DMA_RXCHAN_CFG_HBU_S	7
#define    PAS_DMA_RXCHAN_CFG_HBU(x)	(((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \