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

Commit afea0365 authored by Giuseppe Cavallaro's avatar Giuseppe Cavallaro Committed by David S. Miller
Browse files

stmmac: rework DMA bus setting and introduce new platform AXI structure



This patch restructures the DMA bus settings and this is done
by introducing a new platform structure used for programming
the AXI Bus Mode Register inside the DMA module.
This structure can be populated from device-tree as documented in the
binding txt file.

After initializing the DMA, the AXI register can be optionally tuned
for platform drivers based.
This patch also reworks some parameters to make coherent the DMA
configuration now that AXI register is introduced.
For example, the burst_len is managed by using the mentioned axi
support above; so the snps,burst-len parameter has been removed.
It makes sense to provide the AAL parameter from DT to Address-Aligned
Beats inside the Register0 and review the PBL settings when initialize
the engine.

For PCI glue, rebuilding the story of this setting, it
was added to align a configuration so not for fixing some
known problem. No issue raised after this patch.
It is safe to use the default burst length instead of
tuning it to the maximum value

Signed-off-by: default avatarGiuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: default avatarAlexandre TORGUE <alexandre.torgue@st.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 495db273
Loading
Loading
Loading
Loading
+37 −17
Original line number Diff line number Diff line
@@ -17,7 +17,25 @@ Required properties:
	The 1st cell is reset pre-delay in micro seconds.
	The 2nd cell is reset pulse in micro seconds.
	The 3rd cell is reset post-delay in micro seconds.

Optional properties:
- resets: Should contain a phandle to the STMMAC reset signal, if any
- reset-names: Should contain the reset signal name "stmmaceth", if a
	reset phandle is given
- max-frame-size: See ethernet.txt file in the same directory
- clocks: If present, the first clock should be the GMAC main clock and
  the second clock should be peripheral's register interface clock. Further
  clocks may be specified in derived bindings.
- clock-names: One name for each entry in the clocks property, the
  first one should be "stmmaceth" and the second one should be "pclk".
- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is
  available this clock is used for programming the Timestamp Addend Register.
  If not passed then the system clock will be used and this is fine on some
  platforms.
- tx-fifo-depth: See ethernet.txt file in the same directory
- rx-fifo-depth: See ethernet.txt file in the same directory
- snps,pbl		Programmable Burst Length
- snps,aal		Address-Aligned Beats
- snps,fixed-burst	Program the DMA to use the fixed burst mode
- snps,mixed-burst	Program the DMA to use the mixed burst mode
- snps,force_thresh_dma_mode	Force DMA to use the threshold mode for
@@ -29,27 +47,28 @@ Required properties:
				supported by this device instance
- snps,perfect-filter-entries:	Number of perfect filter entries supported
				by this device instance

Optional properties:
- resets: Should contain a phandle to the STMMAC reset signal, if any
- reset-names: Should contain the reset signal name "stmmaceth", if a
	reset phandle is given
- max-frame-size: See ethernet.txt file in the same directory
- clocks: If present, the first clock should be the GMAC main clock
  The optional second clock should be peripheral's register interface clock.
  The third optional clock should be the ptp reference clock.
  Further clocks may be specified in derived bindings.
- clock-names: One name for each entry in the clocks property.
  The first one should be "stmmaceth".
  The optional second one should be "pclk".
  The optional third one should be "clk_ptp_ref".
- snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register.
- tx-fifo-depth: See ethernet.txt file in the same directory
- rx-fifo-depth: See ethernet.txt file in the same directory
- AXI BUS Mode parameters: below the list of all the parameters to program the
			   AXI register inside the DMA module:
	- snps,lpi_en: enable Low Power Interface
	- snps,xit_frm: unlock on WoL
	- snps,wr_osr_lmt: max write oustanding req. limit
	- snps,rd_osr_lmt: max read oustanding req. limit
	- snps,kbbe: do not cross 1KiB boundary.
	- snps,axi_all: align address
	- snps,blen: this is a vector of supported burst length.
	- snps,fb: fixed-burst
	- snps,mb: mixed-burst
	- snps,rb: rebuild INCRx Burst
- mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus.

Examples:

	stmmac_axi_setup: stmmac-axi-config {
		snps,wr_osr_lmt = <0xf>;
		snps,rd_osr_lmt = <0xf>;
		snps,blen = <256 128 64 32 0 0 0>;
	};

	gmac0: ethernet@e0800000 {
		compatible = "st,spear600-gmac";
		reg = <0xe0800000 0x8000>;
@@ -65,6 +84,7 @@ Examples:
		tx-fifo-depth = <16384>;
		clocks = <&clock>;
		clock-names = "stmmaceth";
		snps,axi-config = <&stmmac_axi_setup>;
		mdio0 {
			#address-cells = <1>;
			#size-cells = <0>;
+4 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/stmmac.h>
#include <linux/phy.h>
#include <linux/module.h>
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -378,7 +379,9 @@ struct stmmac_dma_ops {
	/* DMA core initialization */
	int (*reset)(void __iomem *ioaddr);
	void (*init)(void __iomem *ioaddr, int pbl, int fb, int mb,
		     int burst_len, u32 dma_tx, u32 dma_rx, int atds);
		     int aal, u32 dma_tx, u32 dma_rx, int atds);
	/* Configure the AXI Bus Mode Register */
	void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi);
	/* Dump DMA registers */
	void (*dump_regs) (void __iomem *ioaddr);
	/* Set tx/rx threshold in the csr6 register
+1 −1
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ enum rx_tx_priority_ratio {
#define DMA_BUS_MODE_RPBL_MASK	0x003e0000	/* Rx-Programmable Burst Len */
#define DMA_BUS_MODE_RPBL_SHIFT	17
#define DMA_BUS_MODE_USP	0x00800000
#define DMA_BUS_MODE_PBL	0x01000000
#define DMA_BUS_MODE_MAXPBL	0x01000000
#define DMA_BUS_MODE_AAL	0x02000000

/* DMA CRS Control and Status Register Mapping */
+68 −31
Original line number Diff line number Diff line
@@ -30,24 +30,76 @@
#include "dwmac1000.h"
#include "dwmac_dma.h"

static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
{
	u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
	int i;

	pr_info("dwmac1000: Master AXI performs %s burst length\n",
		!(value & DMA_AXI_UNDEF) ? "fixed" : "any");

	if (axi->axi_lpi_en)
		value |= DMA_AXI_EN_LPI;
	if (axi->axi_xit_frm)
		value |= DMA_AXI_LPI_XIT_FRM;

	value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) <<
		 DMA_AXI_WR_OSR_LMT_SHIFT;

	value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) <<
		 DMA_AXI_RD_OSR_LMT_SHIFT;

	/* Depending on the UNDEF bit the Master AXI will perform any burst
	 * length according to the BLEN programmed (by default all BLEN are
	 * set).
	 */
	for (i = 0; i < AXI_BLEN; i++) {
		switch (axi->axi_blen[i]) {
		case 256:
			value |= DMA_AXI_BLEN256;
			break;
		case 128:
			value |= DMA_AXI_BLEN128;
			break;
		case 64:
			value |= DMA_AXI_BLEN64;
			break;
		case 32:
			value |= DMA_AXI_BLEN32;
			break;
		case 16:
			value |= DMA_AXI_BLEN16;
			break;
		case 8:
			value |= DMA_AXI_BLEN8;
			break;
		case 4:
			value |= DMA_AXI_BLEN4;
			break;
		}
	}

	writel(value, ioaddr + DMA_AXI_BUS_MODE);
}

static void dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
			       int burst_len, u32 dma_tx, u32 dma_rx, int atds)
			       int aal, u32 dma_tx, u32 dma_rx, int atds)
{
	u32 value;
	u32 value = readl(ioaddr + DMA_BUS_MODE);

	/*
	 * Set the DMA PBL (Programmable Burst Length) mode
	 * Before stmmac core 3.50 this mode bit was 4xPBL, and
	 * Set the DMA PBL (Programmable Burst Length) mode.
	 *
	 * Note: before stmmac core 3.50 this mode bit was 4xPBL, and
	 * post 3.5 mode bit acts as 8*PBL.
	 * For core rev < 3.5, when the core is set for 4xPBL mode, the
	 * DMA transfers the data in 4, 8, 16, 32, 64 & 128 beats
	 * depending on pbl value.
	 * For core rev > 3.5, when the core is set for 8xPBL mode, the
	 * DMA transfers the data in 8, 16, 32, 64, 128 & 256 beats
	 * depending on pbl value.
	 *
	 * This configuration doesn't take care about the Separate PBL
	 * so only the bits: 13-8 are programmed with the PBL passed from the
	 * platform.
	 */
	value = DMA_BUS_MODE_PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
				    (pbl << DMA_BUS_MODE_RPBL_SHIFT));
	value |= DMA_BUS_MODE_MAXPBL;
	value &= ~DMA_BUS_MODE_PBL_MASK;
	value |= (pbl << DMA_BUS_MODE_PBL_SHIFT);

	/* Set the Fixed burst mode */
	if (fb)
@@ -60,26 +112,10 @@ static void dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
	if (atds)
		value |= DMA_BUS_MODE_ATDS;

	writel(value, ioaddr + DMA_BUS_MODE);
	if (aal)
		value |= DMA_BUS_MODE_AAL;

	/* In case of GMAC AXI configuration, program the DMA_AXI_BUS_MODE
	 * for supported bursts.
	 *
	 * Note: This is applicable only for revision GMACv3.61a. For
	 * older version this register is reserved and shall have no
	 * effect.
	 *
	 * Note:
	 *  For Fixed Burst Mode: if we directly write 0xFF to this
	 *  register using the configurations pass from platform code,
	 *  this would ensure that all bursts supported by core are set
	 *  and those which are not supported would remain ineffective.
	 *
	 *  For Non Fixed Burst Mode: provide the maximum value of the
	 *  burst length. Any burst equal or below the provided burst
	 *  length would be allowed to perform.
	 */
	writel(burst_len, ioaddr + DMA_AXI_BUS_MODE);
	writel(value, ioaddr + DMA_BUS_MODE);

	/* Mask interrupts by writing to CSR7 */
	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
@@ -192,6 +228,7 @@ static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt)
const struct stmmac_dma_ops dwmac1000_dma_ops = {
	.reset = dwmac_dma_reset,
	.init = dwmac1000_dma_init,
	.axi = dwmac1000_dma_axi,
	.dump_regs = dwmac1000_dump_dma_regs,
	.dma_mode = dwmac1000_dma_operation_mode,
	.enable_dma_transmission = dwmac_enable_dma_transmission,
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@
#include "dwmac_dma.h"

static void dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
			      int burst_len, u32 dma_tx, u32 dma_rx, int atds)
			      int aal, u32 dma_tx, u32 dma_rx, int atds)
{
	/* Enable Application Access by writing to DMA CSR0 */
	writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
Loading