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

Commit 7e97a194 authored by Esben Haabendal's avatar Esben Haabendal Committed by David S. Miller
Browse files

net: ll_temac: Allow configuration of IRQ coalescing



This allows custom setup of IRQ coalescing for platforms using legacy
platform_device. The irq timeout and count parameters can be used for
tuning cpu load vs. latency.

I have maintained the 0x00000400 bit in TX_CHNL_CTRL.  It is specified as
unused in the documentation I have available.  It does not make any
difference in the hardware I have available, so it is left in to not risk
breaking other platforms where it might be used.

Signed-off-by: default avatarEsben Haabendal <esben@geanix.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 901d14ab
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -375,6 +375,10 @@ struct temac_local {
	int tx_bd_next;
	int tx_bd_tail;
	int rx_bd_ci;

	/* DMA channel control setup */
	u32 tx_chnl_ctrl;
	u32 rx_chnl_ctrl;
};

/* Wrappers for temac_ior()/temac_iow() function pointers above */
+28 −12
Original line number Diff line number Diff line
@@ -304,18 +304,15 @@ static int temac_dma_bd_init(struct net_device *ndev)
		lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND);
	}

	lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 |
					  CHNL_CTRL_IRQ_EN |
					  CHNL_CTRL_IRQ_DLY_EN |
					  CHNL_CTRL_IRQ_COAL_EN);
	/* 0x10220483 */
	/* 0x00100483 */
	lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 |
					  CHNL_CTRL_IRQ_EN |
					  CHNL_CTRL_IRQ_DLY_EN |
					  CHNL_CTRL_IRQ_COAL_EN |
					  CHNL_CTRL_IRQ_IOE);
	/* 0xff010283 */
	/* Configure DMA channel (irq setup) */
	lp->dma_out(lp, TX_CHNL_CTRL, lp->tx_chnl_ctrl |
		    0x00000400 | // Use 1 Bit Wide Counters. Currently Not Used!
		    CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_ERR_EN |
		    CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN);
	lp->dma_out(lp, RX_CHNL_CTRL, lp->rx_chnl_ctrl |
		    CHNL_CTRL_IRQ_IOE |
		    CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_ERR_EN |
		    CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN);

	lp->dma_out(lp, RX_CURDESC_PTR,  lp->rx_bd_p);
	lp->dma_out(lp, RX_TAILDESC_PTR,
@@ -1191,6 +1188,13 @@ static int temac_probe(struct platform_device *pdev)
		lp->rx_irq = irq_of_parse_and_map(dma_np, 0);
		lp->tx_irq = irq_of_parse_and_map(dma_np, 1);

		/* Use defaults for IRQ delay/coalescing setup.  These
		 * are configuration values, so does not belong in
		 * device-tree.
		 */
		lp->tx_chnl_ctrl = 0x10220000;
		lp->rx_chnl_ctrl = 0xff070000;

		/* Finished with the DMA node; drop the reference */
		of_node_put(dma_np);
	} else if (pdata) {
@@ -1214,6 +1218,18 @@ static int temac_probe(struct platform_device *pdev)
		/* Get DMA RX and TX interrupts */
		lp->rx_irq = platform_get_irq(pdev, 0);
		lp->tx_irq = platform_get_irq(pdev, 1);

		/* IRQ delay/coalescing setup */
		if (pdata->tx_irq_timeout || pdata->tx_irq_count)
			lp->tx_chnl_ctrl = (pdata->tx_irq_timeout << 24) |
				(pdata->tx_irq_count << 16);
		else
			lp->tx_chnl_ctrl = 0x10220000;
		if (pdata->rx_irq_timeout || pdata->rx_irq_count)
			lp->rx_chnl_ctrl = (pdata->rx_irq_timeout << 24) |
				(pdata->rx_irq_count << 16);
		else
			lp->rx_chnl_ctrl = 0xff070000;
	}

	/* Error handle returned DMA RX and TX interrupts */
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,11 @@ struct ll_temac_platform_data {
	 * they share the same DCR bus bridge.
	 */
	struct mutex *indirect_mutex;
	/* DMA channel control setup */
	u8 tx_irq_timeout;	/* TX Interrupt Delay Time-out */
	u8 tx_irq_count;	/* TX Interrupt Coalescing Threshold Count */
	u8 rx_irq_timeout;	/* RX Interrupt Delay Time-out */
	u8 rx_irq_count;	/* RX Interrupt Coalescing Threshold Count */
};

#endif /* __LINUX_XILINX_LL_TEMAC_H */