[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <787569df0c389f5a1d2695d7fb9d282842686d1c.1691047285.git.chenfeiyang@loongson.cn>
Date: Thu, 3 Aug 2023 19:28:04 +0800
From: Feiyang Chen <chenfeiyang@...ngson.cn>
To: andrew@...n.ch,
hkallweit1@...il.com,
peppe.cavallaro@...com,
alexandre.torgue@...s.st.com,
joabreu@...opsys.com,
chenhuacai@...ngson.cn
Cc: Feiyang Chen <chenfeiyang@...ngson.cn>,
linux@...linux.org.uk,
dongbiao@...ngson.cn,
loongson-kernel@...ts.loongnix.cn,
netdev@...r.kernel.org,
loongarch@...ts.linux.dev,
chris.chenfeiyang@...il.com
Subject: [PATCH v3 02/16] net: stmmac: dwmac1000: Allow platforms to choose some register offsets
Some platforms have dwmac1000 implementations that have a different
address space layout than the default. Add new struct dwmac_regs to
allow a platform driver to choose the appropriate register offsets.
Signed-off-by: Feiyang Chen <chenfeiyang@...ngson.cn>
---
.../ethernet/stmicro/stmmac/dwmac1000_core.c | 3 +
.../ethernet/stmicro/stmmac/dwmac1000_dma.c | 25 +++--
.../ethernet/stmicro/stmmac/dwmac100_core.c | 3 +
.../ethernet/stmicro/stmmac/dwmac100_dma.c | 22 +++--
.../net/ethernet/stmicro/stmmac/dwmac_dma.h | 55 +----------
.../net/ethernet/stmicro/stmmac/dwmac_lib.c | 97 ++++++++++++++++---
include/linux/stmmac.h | 61 ++++++++++++
7 files changed, 187 insertions(+), 79 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index b52793edf62f..6b28f08c8640 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -19,6 +19,7 @@
#include "stmmac.h"
#include "stmmac_pcs.h"
#include "dwmac1000.h"
+#include "dwmac_dma.h"
static void dwmac1000_core_init(struct mac_device_info *hw,
struct net_device *dev)
@@ -533,6 +534,8 @@ int dwmac1000_setup(struct stmmac_priv *priv)
dev_info(priv->device, "\tDWMAC1000\n");
+ priv->plat->dwmac_regs = &dwmac_default_dma_regs;
+
priv->dev->priv_flags |= IFF_UNICAST_FLT;
mac->pcsr = priv->ioaddr;
mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index ce0e6ca6f3a2..3996dea4b1e3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -15,10 +15,12 @@
#include <asm/io.h>
#include "dwmac1000.h"
#include "dwmac_dma.h"
+#include "stmmac.h"
static void dwmac1000_dma_axi(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_axi *axi)
{
+ const struct dwmac_dma_axi *dma_axi = priv->plat->dwmac_regs->axi;
u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
int i;
@@ -30,13 +32,13 @@ static void dwmac1000_dma_axi(struct stmmac_priv *priv, void __iomem *ioaddr,
if (axi->axi_xit_frm)
value |= DMA_AXI_LPI_XIT_FRM;
- value &= ~DMA_AXI_WR_OSR_LMT;
- value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) <<
- DMA_AXI_WR_OSR_LMT_SHIFT;
+ value &= ~dma_axi->wr_osr_lmt;
+ value |= (axi->axi_wr_osr_lmt & dma_axi->wr_osr_lmt_mask) <<
+ dma_axi->wr_osr_lmt_shift;
- value &= ~DMA_AXI_RD_OSR_LMT;
- value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) <<
- DMA_AXI_RD_OSR_LMT_SHIFT;
+ value &= ~dma_axi->rd_osr_lmt;
+ 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
@@ -74,6 +76,7 @@ static void dwmac1000_dma_axi(struct stmmac_priv *priv, void __iomem *ioaddr,
static void dwmac1000_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, int atds)
{
+ u32 mask = priv->plat->dwmac_regs->intr_ena->default_mask;
u32 value = readl(ioaddr + DMA_BUS_MODE);
int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
@@ -108,7 +111,7 @@ static void dwmac1000_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
writel(value, ioaddr + DMA_BUS_MODE);
/* Mask interrupts by writing to CSR7 */
- writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+ writel(mask, ioaddr + DMA_INTR_ENA);
}
static void dwmac1000_dma_init_rx(struct stmmac_priv *priv,
@@ -116,8 +119,10 @@ static void dwmac1000_dma_init_rx(struct stmmac_priv *priv,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t dma_rx_phy, u32 chan)
{
+ u32 addr = priv->plat->dwmac_regs->addrs->rcv_base_addr;
+
/* RX descriptor base address list must be written into DMA CSR3 */
- writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR);
+ writel(lower_32_bits(dma_rx_phy), ioaddr + addr);
}
static void dwmac1000_dma_init_tx(struct stmmac_priv *priv,
@@ -125,8 +130,10 @@ static void dwmac1000_dma_init_tx(struct stmmac_priv *priv,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t dma_tx_phy, u32 chan)
{
+ u32 addr = priv->plat->dwmac_regs->addrs->tx_base_addr;
+
/* TX descriptor base address list must be written into DMA CSR4 */
- writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR);
+ writel(lower_32_bits(dma_tx_phy), ioaddr + addr);
}
static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index c03623edeb75..73ee16549775 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -18,6 +18,7 @@
#include <asm/io.h>
#include "stmmac.h"
#include "dwmac100.h"
+#include "dwmac_dma.h"
static void dwmac100_core_init(struct mac_device_info *hw,
struct net_device *dev)
@@ -177,6 +178,8 @@ int dwmac100_setup(struct stmmac_priv *priv)
dev_info(priv->device, "\tDWMAC100\n");
+ priv->plat->dwmac_regs = &dwmac_default_dma_regs;
+
mac->pcsr = priv->ioaddr;
mac->link.duplex = MAC_CONTROL_F;
mac->link.speed10 = 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
index e6ae230fa453..be9e8fad69f9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -17,32 +17,39 @@
#include <asm/io.h>
#include "dwmac100.h"
#include "dwmac_dma.h"
+#include "stmmac.h"
static void dwmac100_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, int atds)
{
+ u32 mask = priv->plat->dwmac_regs->intr_ena->default_mask;
+
/* Enable Application Access by writing to DMA CSR0 */
writel(DMA_BUS_MODE_DEFAULT | (dma_cfg->pbl << DMA_BUS_MODE_PBL_SHIFT),
ioaddr + DMA_BUS_MODE);
/* Mask interrupts by writing to CSR7 */
- writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+ writel(mask, ioaddr + DMA_INTR_ENA);
}
static void dwmac100_dma_init_rx(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t dma_rx_phy, u32 chan)
{
+ u32 addr = priv->plat->dwmac_regs->addrs->rcv_base_addr;
+
/* RX descriptor base addr lists must be written into DMA CSR3 */
- writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR);
+ writel(lower_32_bits(dma_rx_phy), ioaddr + addr);
}
static void dwmac100_dma_init_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t dma_tx_phy, u32 chan)
{
+ u32 addr = priv->plat->dwmac_regs->addrs->tx_base_addr;
+
/* TX descriptor base addr lists must be written into DMA CSR4 */
- writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR);
+ writel(lower_32_bits(dma_tx_phy), ioaddr + addr);
}
/* Store and Forward capability is not used at all.
@@ -69,16 +76,17 @@ static void dwmac100_dma_operation_mode_tx(struct stmmac_priv *priv,
static void dwmac100_dump_dma_regs(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 *reg_space)
{
+ const struct dwmac_dma_addrs *addrs = priv->plat->dwmac_regs->addrs;
int i;
for (i = 0; i < NUM_DWMAC100_DMA_REGS; i++)
reg_space[DMA_BUS_MODE / 4 + i] =
readl(ioaddr + DMA_BUS_MODE + i * 4);
- reg_space[DMA_CUR_TX_BUF_ADDR / 4] =
- readl(ioaddr + DMA_CUR_TX_BUF_ADDR);
- reg_space[DMA_CUR_RX_BUF_ADDR / 4] =
- readl(ioaddr + DMA_CUR_RX_BUF_ADDR);
+ reg_space[addrs->cur_tx_buf_addr / 4] =
+ readl(ioaddr + addrs->cur_tx_buf_addr);
+ reg_space[addrs->cur_rx_buf_addr / 4] =
+ readl(ioaddr + addrs->cur_rx_buf_addr);
}
/* DMA controller has two counters to track the number of the missed frames. */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 77141391bd2f..b2b75b5b6d50 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -15,8 +15,6 @@
#define DMA_BUS_MODE 0x00001000 /* Bus Mode */
#define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */
#define DMA_RCV_POLL_DEMAND 0x00001008 /* Received Poll Demand */
-#define DMA_RCV_BASE_ADDR 0x0000100c /* Receive List Base */
-#define DMA_TX_BASE_ADDR 0x00001010 /* Transmit List Base */
#define DMA_STATUS 0x00001014 /* Status Register */
#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */
#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */
@@ -33,16 +31,6 @@
#define DMA_AXI_EN_LPI BIT(31)
#define DMA_AXI_LPI_XIT_FRM BIT(30)
-#define DMA_AXI_WR_OSR_LMT GENMASK(23, 20)
-#define DMA_AXI_WR_OSR_LMT_SHIFT 20
-#define DMA_AXI_WR_OSR_LMT_MASK 0xf
-#define DMA_AXI_RD_OSR_LMT GENMASK(19, 16)
-#define DMA_AXI_RD_OSR_LMT_SHIFT 16
-#define DMA_AXI_RD_OSR_LMT_MASK 0xf
-
-#define DMA_AXI_OSR_MAX 0xf
-#define DMA_AXI_MAX_OSR_LIMIT ((DMA_AXI_OSR_MAX << DMA_AXI_WR_OSR_LMT_SHIFT) | \
- (DMA_AXI_OSR_MAX << DMA_AXI_RD_OSR_LMT_SHIFT))
#define DMA_AXI_1KBBE BIT(13)
#define DMA_AXI_AAL BIT(12)
#define DMA_AXI_BLEN256 BIT(7)
@@ -61,26 +49,20 @@
#define DMA_AXI_BURST_LEN_MASK 0x000000FE
-#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
-#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
#define DMA_HW_FEATURE 0x00001058 /* HW Feature Register */
+#define DMA_FUNC_CONFIG 0x00001080
/* DMA Control register defines */
#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */
#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */
/* DMA Normal interrupt */
-#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */
#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */
#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavailable */
#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */
#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */
-#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
- DMA_INTR_ENA_TIE)
-
/* DMA Abnormal interrupt */
-#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */
#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */
#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */
#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */
@@ -91,30 +73,17 @@
#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */
#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */
-#define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
- DMA_INTR_ENA_UNE)
-
/* DMA default interrupt mask */
-#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
#define DMA_INTR_DEFAULT_RX (DMA_INTR_ENA_RIE)
#define DMA_INTR_DEFAULT_TX (DMA_INTR_ENA_TIE)
/* DMA Status register defines */
-#define DMA_STATUS_GLPII 0x40000000 /* GMAC LPI interrupt */
#define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */
#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */
#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */
-#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */
#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */
#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */
-#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */
-#define DMA_STATUS_TS_SHIFT 20
-#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */
-#define DMA_STATUS_RS_SHIFT 17
-#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */
-#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */
#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */
-#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */
#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */
#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */
#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */
@@ -128,30 +97,12 @@
#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
-#define DMA_STATUS_MSK_COMMON (DMA_STATUS_NIS | \
- DMA_STATUS_AIS | \
- DMA_STATUS_FBI)
-
-#define DMA_STATUS_MSK_RX (DMA_STATUS_ERI | \
- DMA_STATUS_RWT | \
- DMA_STATUS_RPS | \
- DMA_STATUS_RU | \
- DMA_STATUS_RI | \
- DMA_STATUS_OVF | \
- DMA_STATUS_MSK_COMMON)
-
-#define DMA_STATUS_MSK_TX (DMA_STATUS_ETI | \
- DMA_STATUS_UNF | \
- DMA_STATUS_TJT | \
- DMA_STATUS_TU | \
- DMA_STATUS_TPS | \
- DMA_STATUS_TI | \
- DMA_STATUS_MSK_COMMON)
-
#define NUM_DWMAC100_DMA_REGS 9
#define NUM_DWMAC1000_DMA_REGS 23
#define NUM_DWMAC4_DMA_REGS 27
+extern const struct dwmac_regs dwmac_default_dma_regs;
+
void dwmac_enable_dma_transmission(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 chan);
void dwmac_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index 053a8af6d0e1..6411be0f3612 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -10,9 +10,82 @@
#include <linux/iopoll.h>
#include "common.h"
#include "dwmac_dma.h"
+#include "stmmac.h"
#define GMAC_HI_REG_AE 0x80000000
+static const struct dwmac_dma_addrs default_dma_addrs = {
+ .rcv_base_addr = 0x0000100c,
+ .tx_base_addr = 0x00001010,
+ .cur_tx_buf_addr = 0x00001050,
+ .cur_rx_buf_addr = 0x00001054,
+};
+
+static const struct dwmac_dma_axi default_dma_axi = {
+ .wr_osr_lmt = GENMASK(23, 20),
+ .wr_osr_lmt_shift = 20,
+ .wr_osr_lmt_mask = 0xf,
+ .rd_osr_lmt = GENMASK(19, 16),
+ .rd_osr_lmt_shift = 16,
+ .rd_osr_lmt_mask = 0xf,
+ .osr_max = 0xf,
+ /* max_osr_limit = (osr_max << wr_osr_lmt_shift) |
+ * (osr_max << rd_osr_lmt_shift)
+ */
+ .max_osr_limit = (0xf << 20) | (0xf << 16),
+};
+
+static const struct dwmac_dma_intr_ena default_dma_intr_ena = {
+ .nie = 0x00010000,
+ /* normal = nie | DMA_INTR_ENA_RIE | DMA_INTR_ENA_TIE */
+ .normal = 0x00010000 | DMA_INTR_ENA_RIE | DMA_INTR_ENA_TIE,
+ .aie = 0x00008000,
+ /* abnormal = aie | DMA_INTR_ENA_FBE | DMA_INTR_ENA_UNE */
+ .abnormal = 0x00008000 | DMA_INTR_ENA_FBE | DMA_INTR_ENA_UNE,
+ /* default_mask = normal | abnormal */
+ .default_mask = (0x00010000 | DMA_INTR_ENA_RIE | DMA_INTR_ENA_TIE) |
+ (0x00008000 | DMA_INTR_ENA_FBE | DMA_INTR_ENA_UNE),
+};
+
+static const struct dwmac_dma_status default_dma_status = {
+ .glpii = 0x40000000,
+ .gpi = 0x10000000,
+ .gmi = 0x08000000,
+ .gli = 0x04000000,
+ .intr_mask = 0x1ffff,
+ .eb_mask = 0x00380000,
+ .ts_mask = 0x00700000,
+ .ts_shift = 20,
+ .rs_mask = 0x000e0000,
+ .rs_shift = 17,
+ .nis = 0x00010000,
+ .ais = 0x00008000,
+ .fbi = 0x00002000,
+ /* msk_common = nis | ais | fbi */
+ .msk_common = 0x00010000 | 0x00008000 | 0x00002000,
+ /* msk_rx = DMA_STATUS_ERI | DMA_STATUS_RWT | DMA_STATUS_RPS |
+ * DMA_STATUS_RU | DMA_STATUS_RI | DMA_STATUS_OVF |
+ * msk_common
+ */
+ .msk_rx = DMA_STATUS_ERI | DMA_STATUS_RWT | DMA_STATUS_RPS |
+ DMA_STATUS_RU | DMA_STATUS_RI | DMA_STATUS_OVF |
+ 0x00010000 | 0x00008000 | 0x00002000,
+ /* msk_tx = DMA_STATUS_ETI | DMA_STATUS_UNF | DMA_STATUS_TJT |
+ * DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_TI |
+ * msk_common
+ */
+ .msk_tx = DMA_STATUS_ETI | DMA_STATUS_UNF | DMA_STATUS_TJT |
+ DMA_STATUS_TU | DMA_STATUS_TPS | DMA_STATUS_TI |
+ 0x00010000 | 0x00008000 | 0x00002000,
+};
+
+const struct dwmac_regs dwmac_default_dma_regs = {
+ .addrs = &default_dma_addrs,
+ .axi = &default_dma_axi,
+ .intr_ena = &default_dma_intr_ena,
+ .status = &default_dma_status,
+};
+
int dwmac_dma_reset(struct stmmac_priv *priv, void __iomem *ioaddr)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
@@ -92,8 +165,9 @@ void dwmac_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr, u32 chan)
#ifdef DWMAC_DMA_DEBUG
static void show_tx_process_state(unsigned int status)
{
+ u32 status = priv->plat->dwmac_regs->status;
unsigned int state;
- state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
+ state = (status & status->ts_mask) >> status->ts_shift;
switch (state) {
case 0:
@@ -123,8 +197,9 @@ static void show_tx_process_state(unsigned int status)
static void show_rx_process_state(unsigned int status)
{
+ u32 status = priv->plat->dwmac_regs->status;
unsigned int state;
- state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
+ state = (status & status->rs_mask) >> status->rs_shift;
switch (state) {
case 0:
@@ -162,6 +237,7 @@ static void show_rx_process_state(unsigned int status)
int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_extra_stats *x, u32 chan, u32 dir)
{
+ const struct dwmac_dma_status *status = priv->plat->dwmac_regs->status;
int ret = 0;
/* read the status register (CSR5) */
u32 intr_status = readl(ioaddr + DMA_STATUS);
@@ -174,12 +250,12 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
#endif
if (dir == DMA_DIR_RX)
- intr_status &= DMA_STATUS_MSK_RX;
+ intr_status &= status->msk_rx;
else if (dir == DMA_DIR_TX)
- intr_status &= DMA_STATUS_MSK_TX;
+ intr_status &= status->msk_tx;
/* ABNORMAL interrupts */
- if (unlikely(intr_status & DMA_STATUS_AIS)) {
+ if (unlikely(intr_status & status->ais)) {
if (unlikely(intr_status & DMA_STATUS_UNF)) {
ret = tx_hard_error_bump_tc;
x->tx_undeflow_irq++;
@@ -202,13 +278,13 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
x->tx_process_stopped_irq++;
ret = tx_hard_error;
}
- if (unlikely(intr_status & DMA_STATUS_FBI)) {
+ if (unlikely(intr_status & status->fbi)) {
x->fatal_bus_error_irq++;
ret = tx_hard_error;
}
}
/* TX/RX NORMAL interrupts */
- if (likely(intr_status & DMA_STATUS_NIS)) {
+ if (likely(intr_status & status->nis)) {
x->normal_irq_n++;
if (likely(intr_status & DMA_STATUS_RI)) {
u32 value = readl(ioaddr + DMA_INTR_ENA);
@@ -226,12 +302,11 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
x->rx_early_irq++;
}
/* Optional hardware blocks, interrupts should be disabled */
- if (unlikely(intr_status &
- (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
+ if (unlikely(intr_status & (status->gpi | status->gmi | status->gli)))
pr_warn("%s: unexpected status %08x\n", __func__, intr_status);
- /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
- writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
+ /* Clear the interrupt by writing a logic 1 to the CSR5 */
+ writel((intr_status & status->intr_mask), ioaddr + DMA_STATUS);
return ret;
}
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 06090538fe2d..ab979efd57bf 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -204,6 +204,66 @@ struct dwmac4_addrs {
u32 mtl_low_cred_offset;
};
+/* DMA addresses that may be customized by a platform */
+struct dwmac_dma_addrs {
+ u32 chan_offset;
+ u32 rcv_base_addr;
+ u32 rcv_base_addr_shadow1;
+ u32 rcv_base_addr_shadow2;
+ u32 tx_base_addr;
+ u32 cur_tx_buf_addr;
+ u32 cur_rx_buf_addr;
+};
+
+/* DMA AXI registers that may be customized by a platform */
+struct dwmac_dma_axi {
+ u32 wr_osr_lmt;
+ u32 wr_osr_lmt_shift;
+ u32 wr_osr_lmt_mask;
+ u32 rd_osr_lmt;
+ u32 rd_osr_lmt_shift;
+ u32 rd_osr_lmt_mask;
+ u32 osr_max;
+ u32 max_osr_limit;
+};
+
+/* DMA normal and abnormal interrupt that may be customized by a platform */
+struct dwmac_dma_intr_ena {
+ u32 nie;
+ u32 normal;
+ u32 aie;
+ u32 abnormal;
+ u32 default_mask;
+};
+
+/* DMA Status register that may be customized by a platform */
+struct dwmac_dma_status {
+ u32 glpii;
+ u32 gpi;
+ u32 gmi;
+ u32 gli;
+ u32 intr_mask;
+ u32 eb_mask;
+ u32 ts_mask;
+ u32 ts_shift;
+ u32 rs_mask;
+ u32 rs_shift;
+ u32 nis;
+ u32 ais;
+ u32 fbi;
+ u32 msk_common;
+ u32 msk_rx;
+ u32 msk_tx;
+};
+
+/* Registers that may be customized by a platform */
+struct dwmac_regs {
+ const struct dwmac_dma_addrs *addrs;
+ const struct dwmac_dma_axi *axi;
+ const struct dwmac_dma_intr_ena *intr_ena;
+ const struct dwmac_dma_status *status;
+};
+
struct plat_stmmacenet_data {
int bus_id;
int phy_addr;
@@ -294,5 +354,6 @@ struct plat_stmmacenet_data {
bool serdes_up_after_phy_linkup;
const struct dwmac4_addrs *dwmac4_addrs;
bool has_integrated_pcs;
+ const struct dwmac_regs *dwmac_regs;
};
#endif
--
2.39.3
Powered by blists - more mailing lists