Skip to content

Commit

Permalink
net: stmmac: dwmac4: Allow platforms to specify some DMA/MTL offsets
Browse files Browse the repository at this point in the history
Some platforms have dwmac4 implementations that have a different
address space layout than the default, resulting in the need to define
their own DMA/MTL offsets.

Extend the functions to allow a platform driver to indicate what its
addresses are, overriding the defaults.

Signed-off-by: Andrew Halaney <ahalaney@redhat.com>
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Andrew Halaney authored and Paolo Abeni committed Apr 13, 2023
1 parent 1d84b48 commit 33719b5
Show file tree
Hide file tree
Showing 6 changed files with 293 additions and 141 deletions.
101 changes: 84 additions & 17 deletions drivers/net/ethernet/stmicro/stmmac/dwmac4.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,25 @@ enum power_event {

#define MTL_CHAN_BASE_ADDR 0x00000d00
#define MTL_CHAN_BASE_OFFSET 0x40
#define MTL_CHANX_BASE_ADDR(x) (MTL_CHAN_BASE_ADDR + \
(x * MTL_CHAN_BASE_OFFSET))

#define MTL_CHAN_TX_OP_MODE(x) MTL_CHANX_BASE_ADDR(x)
#define MTL_CHAN_TX_DEBUG(x) (MTL_CHANX_BASE_ADDR(x) + 0x8)
#define MTL_CHAN_INT_CTRL(x) (MTL_CHANX_BASE_ADDR(x) + 0x2c)
#define MTL_CHAN_RX_OP_MODE(x) (MTL_CHANX_BASE_ADDR(x) + 0x30)
#define MTL_CHAN_RX_DEBUG(x) (MTL_CHANX_BASE_ADDR(x) + 0x38)
static inline u32 mtl_chanx_base_addr(const struct dwmac4_addrs *addrs,
const u32 x)
{
u32 addr;

if (addrs)
addr = addrs->mtl_chan + (x * addrs->mtl_chan_offset);
else
addr = MTL_CHAN_BASE_ADDR + (x * MTL_CHAN_BASE_OFFSET);

return addr;
}

#define MTL_CHAN_TX_OP_MODE(addrs, x) mtl_chanx_base_addr(addrs, x)
#define MTL_CHAN_TX_DEBUG(addrs, x) (mtl_chanx_base_addr(addrs, x) + 0x8)
#define MTL_CHAN_INT_CTRL(addrs, x) (mtl_chanx_base_addr(addrs, x) + 0x2c)
#define MTL_CHAN_RX_OP_MODE(addrs, x) (mtl_chanx_base_addr(addrs, x) + 0x30)
#define MTL_CHAN_RX_DEBUG(addrs, x) (mtl_chanx_base_addr(addrs, x) + 0x38)

#define MTL_OP_MODE_RSF BIT(5)
#define MTL_OP_MODE_TXQEN_MASK GENMASK(3, 2)
Expand Down Expand Up @@ -388,40 +399,96 @@ enum power_event {
/* MTL ETS Control register */
#define MTL_ETS_CTRL_BASE_ADDR 0x00000d10
#define MTL_ETS_CTRL_BASE_OFFSET 0x40
#define MTL_ETSX_CTRL_BASE_ADDR(x) (MTL_ETS_CTRL_BASE_ADDR + \
((x) * MTL_ETS_CTRL_BASE_OFFSET))

static inline u32 mtl_etsx_ctrl_base_addr(const struct dwmac4_addrs *addrs,
const u32 x)
{
u32 addr;

if (addrs)
addr = addrs->mtl_ets_ctrl + (x * addrs->mtl_ets_ctrl_offset);
else
addr = MTL_ETS_CTRL_BASE_ADDR + (x * MTL_ETS_CTRL_BASE_OFFSET);

return addr;
}

#define MTL_ETS_CTRL_CC BIT(3)
#define MTL_ETS_CTRL_AVALG BIT(2)

/* MTL Queue Quantum Weight */
#define MTL_TXQ_WEIGHT_BASE_ADDR 0x00000d18
#define MTL_TXQ_WEIGHT_BASE_OFFSET 0x40
#define MTL_TXQX_WEIGHT_BASE_ADDR(x) (MTL_TXQ_WEIGHT_BASE_ADDR + \
((x) * MTL_TXQ_WEIGHT_BASE_OFFSET))

static inline u32 mtl_txqx_weight_base_addr(const struct dwmac4_addrs *addrs,
const u32 x)
{
u32 addr;

if (addrs)
addr = addrs->mtl_txq_weight + (x * addrs->mtl_txq_weight_offset);
else
addr = MTL_TXQ_WEIGHT_BASE_ADDR + (x * MTL_TXQ_WEIGHT_BASE_OFFSET);

return addr;
}

#define MTL_TXQ_WEIGHT_ISCQW_MASK GENMASK(20, 0)

/* MTL sendSlopeCredit register */
#define MTL_SEND_SLP_CRED_BASE_ADDR 0x00000d1c
#define MTL_SEND_SLP_CRED_OFFSET 0x40
#define MTL_SEND_SLP_CREDX_BASE_ADDR(x) (MTL_SEND_SLP_CRED_BASE_ADDR + \
((x) * MTL_SEND_SLP_CRED_OFFSET))

static inline u32 mtl_send_slp_credx_base_addr(const struct dwmac4_addrs *addrs,
const u32 x)
{
u32 addr;

if (addrs)
addr = addrs->mtl_send_slp_cred + (x * addrs->mtl_send_slp_cred_offset);
else
addr = MTL_SEND_SLP_CRED_BASE_ADDR + (x * MTL_SEND_SLP_CRED_OFFSET);

return addr;
}

#define MTL_SEND_SLP_CRED_SSC_MASK GENMASK(13, 0)

/* MTL hiCredit register */
#define MTL_HIGH_CRED_BASE_ADDR 0x00000d20
#define MTL_HIGH_CRED_OFFSET 0x40
#define MTL_HIGH_CREDX_BASE_ADDR(x) (MTL_HIGH_CRED_BASE_ADDR + \
((x) * MTL_HIGH_CRED_OFFSET))

static inline u32 mtl_high_credx_base_addr(const struct dwmac4_addrs *addrs,
const u32 x)
{
u32 addr;

if (addrs)
addr = addrs->mtl_high_cred + (x * addrs->mtl_high_cred_offset);
else
addr = MTL_HIGH_CRED_BASE_ADDR + (x * MTL_HIGH_CRED_OFFSET);

return addr;
}

#define MTL_HIGH_CRED_HC_MASK GENMASK(28, 0)

/* MTL loCredit register */
#define MTL_LOW_CRED_BASE_ADDR 0x00000d24
#define MTL_LOW_CRED_OFFSET 0x40
#define MTL_LOW_CREDX_BASE_ADDR(x) (MTL_LOW_CRED_BASE_ADDR + \
((x) * MTL_LOW_CRED_OFFSET))

static inline u32 mtl_low_credx_base_addr(const struct dwmac4_addrs *addrs,
const u32 x)
{
u32 addr;

if (addrs)
addr = addrs->mtl_low_cred + (x * addrs->mtl_low_cred_offset);
else
addr = MTL_LOW_CRED_BASE_ADDR + (x * MTL_LOW_CRED_OFFSET);

return addr;
}

#define MTL_HIGH_CRED_LC_MASK GENMASK(28, 0)

Expand Down
36 changes: 22 additions & 14 deletions drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,14 @@ static void dwmac4_set_mtl_tx_queue_weight(struct stmmac_priv *priv,
struct mac_device_info *hw,
u32 weight, u32 queue)
{
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
void __iomem *ioaddr = hw->pcsr;
u32 value = readl(ioaddr + MTL_TXQX_WEIGHT_BASE_ADDR(queue));
u32 value = readl(ioaddr + mtl_txqx_weight_base_addr(dwmac4_addrs,
queue));

value &= ~MTL_TXQ_WEIGHT_ISCQW_MASK;
value |= weight & MTL_TXQ_WEIGHT_ISCQW_MASK;
writel(value, ioaddr + MTL_TXQX_WEIGHT_BASE_ADDR(queue));
writel(value, ioaddr + mtl_txqx_weight_base_addr(dwmac4_addrs, queue));
}

static void dwmac4_map_mtl_dma(struct mac_device_info *hw, u32 queue, u32 chan)
Expand All @@ -233,6 +235,7 @@ static void dwmac4_config_cbs(struct stmmac_priv *priv,
u32 send_slope, u32 idle_slope,
u32 high_credit, u32 low_credit, u32 queue)
{
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
void __iomem *ioaddr = hw->pcsr;
u32 value;

Expand All @@ -243,31 +246,33 @@ static void dwmac4_config_cbs(struct stmmac_priv *priv,
pr_debug("\tlow_credit: 0x%08x\n", low_credit);

/* enable AV algorithm */
value = readl(ioaddr + MTL_ETSX_CTRL_BASE_ADDR(queue));
value = readl(ioaddr + mtl_etsx_ctrl_base_addr(dwmac4_addrs, queue));
value |= MTL_ETS_CTRL_AVALG;
value |= MTL_ETS_CTRL_CC;
writel(value, ioaddr + MTL_ETSX_CTRL_BASE_ADDR(queue));
writel(value, ioaddr + mtl_etsx_ctrl_base_addr(dwmac4_addrs, queue));

/* configure send slope */
value = readl(ioaddr + MTL_SEND_SLP_CREDX_BASE_ADDR(queue));
value = readl(ioaddr + mtl_send_slp_credx_base_addr(dwmac4_addrs,
queue));
value &= ~MTL_SEND_SLP_CRED_SSC_MASK;
value |= send_slope & MTL_SEND_SLP_CRED_SSC_MASK;
writel(value, ioaddr + MTL_SEND_SLP_CREDX_BASE_ADDR(queue));
writel(value, ioaddr + mtl_send_slp_credx_base_addr(dwmac4_addrs,
queue));

/* configure idle slope (same register as tx weight) */
dwmac4_set_mtl_tx_queue_weight(priv, hw, idle_slope, queue);

/* configure high credit */
value = readl(ioaddr + MTL_HIGH_CREDX_BASE_ADDR(queue));
value = readl(ioaddr + mtl_high_credx_base_addr(dwmac4_addrs, queue));
value &= ~MTL_HIGH_CRED_HC_MASK;
value |= high_credit & MTL_HIGH_CRED_HC_MASK;
writel(value, ioaddr + MTL_HIGH_CREDX_BASE_ADDR(queue));
writel(value, ioaddr + mtl_high_credx_base_addr(dwmac4_addrs, queue));

/* configure high credit */
value = readl(ioaddr + MTL_LOW_CREDX_BASE_ADDR(queue));
value = readl(ioaddr + mtl_low_credx_base_addr(dwmac4_addrs, queue));
value &= ~MTL_HIGH_CRED_LC_MASK;
value |= low_credit & MTL_HIGH_CRED_LC_MASK;
writel(value, ioaddr + MTL_LOW_CREDX_BASE_ADDR(queue));
writel(value, ioaddr + mtl_low_credx_base_addr(dwmac4_addrs, queue));
}

static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space)
Expand Down Expand Up @@ -764,6 +769,7 @@ static void dwmac4_phystatus(void __iomem *ioaddr, struct stmmac_extra_stats *x)
static int dwmac4_irq_mtl_status(struct stmmac_priv *priv,
struct mac_device_info *hw, u32 chan)
{
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
void __iomem *ioaddr = hw->pcsr;
u32 mtl_int_qx_status;
int ret = 0;
Expand All @@ -773,12 +779,13 @@ static int dwmac4_irq_mtl_status(struct stmmac_priv *priv,
/* Check MTL Interrupt */
if (mtl_int_qx_status & MTL_INT_QX(chan)) {
/* read Queue x Interrupt status */
u32 status = readl(ioaddr + MTL_CHAN_INT_CTRL(chan));
u32 status = readl(ioaddr + MTL_CHAN_INT_CTRL(dwmac4_addrs,
chan));

if (status & MTL_RX_OVERFLOW_INT) {
/* clear Interrupt */
writel(status | MTL_RX_OVERFLOW_INT,
ioaddr + MTL_CHAN_INT_CTRL(chan));
ioaddr + MTL_CHAN_INT_CTRL(dwmac4_addrs, chan));
ret = CORE_IRQ_MTL_RX_OVERFLOW;
}
}
Expand Down Expand Up @@ -840,11 +847,12 @@ static void dwmac4_debug(struct stmmac_priv *priv, void __iomem *ioaddr,
struct stmmac_extra_stats *x,
u32 rx_queues, u32 tx_queues)
{
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
u32 value;
u32 queue;

for (queue = 0; queue < tx_queues; queue++) {
value = readl(ioaddr + MTL_CHAN_TX_DEBUG(queue));
value = readl(ioaddr + MTL_CHAN_TX_DEBUG(dwmac4_addrs, queue));

if (value & MTL_DEBUG_TXSTSFSTS)
x->mtl_tx_status_fifo_full++;
Expand All @@ -869,7 +877,7 @@ static void dwmac4_debug(struct stmmac_priv *priv, void __iomem *ioaddr,
}

for (queue = 0; queue < rx_queues; queue++) {
value = readl(ioaddr + MTL_CHAN_RX_DEBUG(queue));
value = readl(ioaddr + MTL_CHAN_RX_DEBUG(dwmac4_addrs, queue));

if (value & MTL_DEBUG_RXFSTS_MASK) {
u32 rxfsts = (value & MTL_DEBUG_RXFSTS_MASK)
Expand Down
Loading

0 comments on commit 33719b5

Please sign in to comment.