Skip to content

Commit

Permalink
Merge branch 'net-asp22-optimizations'
Browse files Browse the repository at this point in the history
Justin Chen says:

====================
Support for ASP 2.2 and optimizations

ASP 2.2 adds some power savings during low power modes.

Also make various improvements when entering low power modes and
reduce MDIO traffic by hooking up interrupts.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 1, 2024
2 parents fc809e1 + cc7f105 commit 7779f26
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 118 deletions.
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/net/brcm,asp-v2.0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ description: Broadcom Ethernet controller first introduced with 72165
properties:
compatible:
oneOf:
- items:
- enum:
- brcm,bcm74165b0-asp
- const: brcm,asp-v2.2
- items:
- enum:
- brcm,bcm74165-asp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ properties:
- brcm,genet-mdio-v5
- brcm,asp-v2.0-mdio
- brcm,asp-v2.1-mdio
- brcm,asp-v2.2-mdio
- brcm,unimac-mdio

reg:
Expand Down
90 changes: 82 additions & 8 deletions drivers/net/ethernet/broadcom/asp2/bcmasp.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ static void _intr2_mask_set(struct bcmasp_priv *priv, u32 mask)
priv->irq_mask |= mask;
}

void bcmasp_enable_phy_irq(struct bcmasp_intf *intf, int en)
{
struct bcmasp_priv *priv = intf->parent;

/* Only supported with internal phys */
if (!intf->internal_phy)
return;

if (en)
_intr2_mask_clear(priv, ASP_INTR2_PHY_EVENT(intf->channel));
else
_intr2_mask_set(priv, ASP_INTR2_PHY_EVENT(intf->channel));
}

void bcmasp_enable_tx_irq(struct bcmasp_intf *intf, int en)
{
struct bcmasp_priv *priv = intf->parent;
Expand Down Expand Up @@ -79,6 +93,9 @@ static void bcmasp_intr2_handling(struct bcmasp_intf *intf, u32 status)
__napi_schedule_irqoff(&intf->tx_napi);
}
}

if (status & ASP_INTR2_PHY_EVENT(intf->channel))
phy_mac_interrupt(intf->ndev->phydev);
}

static irqreturn_t bcmasp_isr(int irq, void *data)
Expand Down Expand Up @@ -972,7 +989,26 @@ static void bcmasp_core_init(struct bcmasp_priv *priv)
ASP_INTR2_CLEAR);
}

static void bcmasp_core_clock_select(struct bcmasp_priv *priv, bool slow)
static void bcmasp_core_clock_select_many(struct bcmasp_priv *priv, bool slow)
{
u32 reg;

reg = ctrl2_core_rl(priv, ASP_CTRL2_CORE_CLOCK_SELECT);
if (slow)
reg &= ~ASP_CTRL2_CORE_CLOCK_SELECT_MAIN;
else
reg |= ASP_CTRL2_CORE_CLOCK_SELECT_MAIN;
ctrl2_core_wl(priv, reg, ASP_CTRL2_CORE_CLOCK_SELECT);

reg = ctrl2_core_rl(priv, ASP_CTRL2_CPU_CLOCK_SELECT);
if (slow)
reg &= ~ASP_CTRL2_CPU_CLOCK_SELECT_MAIN;
else
reg |= ASP_CTRL2_CPU_CLOCK_SELECT_MAIN;
ctrl2_core_wl(priv, reg, ASP_CTRL2_CPU_CLOCK_SELECT);
}

static void bcmasp_core_clock_select_one(struct bcmasp_priv *priv, bool slow)
{
u32 reg;

Expand Down Expand Up @@ -1166,6 +1202,24 @@ static void bcmasp_wol_irq_destroy_per_intf(struct bcmasp_priv *priv)
}
}

static void bcmasp_eee_fixup(struct bcmasp_intf *intf, bool en)
{
u32 reg, phy_lpi_overwrite;

reg = rx_edpkt_core_rl(intf->parent, ASP_EDPKT_SPARE_REG);
phy_lpi_overwrite = intf->internal_phy ? ASP_EDPKT_SPARE_REG_EPHY_LPI :
ASP_EDPKT_SPARE_REG_GPHY_LPI;

if (en)
reg |= phy_lpi_overwrite;
else
reg &= ~phy_lpi_overwrite;

rx_edpkt_core_wl(intf->parent, reg, ASP_EDPKT_SPARE_REG);

usleep_range(50, 100);
}

static struct bcmasp_hw_info v20_hw_info = {
.rx_ctrl_flush = ASP_RX_CTRL_FLUSH,
.umac2fb = UMAC2FB_OFFSET,
Expand All @@ -1178,6 +1232,7 @@ static const struct bcmasp_plat_data v20_plat_data = {
.init_wol = bcmasp_init_wol_per_intf,
.enable_wol = bcmasp_enable_wol_per_intf,
.destroy_wol = bcmasp_wol_irq_destroy_per_intf,
.core_clock_select = bcmasp_core_clock_select_one,
.hw_info = &v20_hw_info,
};

Expand All @@ -1194,17 +1249,39 @@ static const struct bcmasp_plat_data v21_plat_data = {
.init_wol = bcmasp_init_wol_shared,
.enable_wol = bcmasp_enable_wol_shared,
.destroy_wol = bcmasp_wol_irq_destroy_shared,
.core_clock_select = bcmasp_core_clock_select_one,
.hw_info = &v21_hw_info,
};

static const struct bcmasp_plat_data v22_plat_data = {
.init_wol = bcmasp_init_wol_shared,
.enable_wol = bcmasp_enable_wol_shared,
.destroy_wol = bcmasp_wol_irq_destroy_shared,
.core_clock_select = bcmasp_core_clock_select_many,
.hw_info = &v21_hw_info,
.eee_fixup = bcmasp_eee_fixup,
};

static void bcmasp_set_pdata(struct bcmasp_priv *priv, const struct bcmasp_plat_data *pdata)
{
priv->init_wol = pdata->init_wol;
priv->enable_wol = pdata->enable_wol;
priv->destroy_wol = pdata->destroy_wol;
priv->core_clock_select = pdata->core_clock_select;
priv->eee_fixup = pdata->eee_fixup;
priv->hw_info = pdata->hw_info;
}

static const struct of_device_id bcmasp_of_match[] = {
{ .compatible = "brcm,asp-v2.0", .data = &v20_plat_data },
{ .compatible = "brcm,asp-v2.1", .data = &v21_plat_data },
{ .compatible = "brcm,asp-v2.2", .data = &v22_plat_data },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, bcmasp_of_match);

static const struct of_device_id bcmasp_mdio_of_match[] = {
{ .compatible = "brcm,asp-v2.2-mdio", },
{ .compatible = "brcm,asp-v2.1-mdio", },
{ .compatible = "brcm,asp-v2.0-mdio", },
{ /* sentinel */ },
Expand Down Expand Up @@ -1265,16 +1342,13 @@ static int bcmasp_probe(struct platform_device *pdev)
if (!pdata)
return dev_err_probe(dev, -EINVAL, "unable to find platform data\n");

priv->init_wol = pdata->init_wol;
priv->enable_wol = pdata->enable_wol;
priv->destroy_wol = pdata->destroy_wol;
priv->hw_info = pdata->hw_info;
bcmasp_set_pdata(priv, pdata);

/* Enable all clocks to ensure successful probing */
bcmasp_core_clock_set(priv, ASP_CTRL_CLOCK_CTRL_ASP_ALL_DISABLE, 0);

/* Switch to the main clock */
bcmasp_core_clock_select(priv, false);
priv->core_clock_select(priv, false);

bcmasp_intr2_mask_set_all(priv);
bcmasp_intr2_clear_all(priv);
Expand Down Expand Up @@ -1381,7 +1455,7 @@ static int __maybe_unused bcmasp_suspend(struct device *d)
*/
bcmasp_core_clock_set(priv, 0, ASP_CTRL_CLOCK_CTRL_ASP_TX_DISABLE);

bcmasp_core_clock_select(priv, true);
priv->core_clock_select(priv, true);

clk_disable_unprepare(priv->clk);

Expand All @@ -1399,7 +1473,7 @@ static int __maybe_unused bcmasp_resume(struct device *d)
return ret;

/* Switch to the main clock domain */
bcmasp_core_clock_select(priv, false);
priv->core_clock_select(priv, false);

/* Re-enable all clocks for re-initialization */
bcmasp_core_clock_set(priv, ASP_CTRL_CLOCK_CTRL_ASP_ALL_DISABLE, 0);
Expand Down
23 changes: 21 additions & 2 deletions drivers/net/ethernet/broadcom/asp2/bcmasp.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#define ASP_INTR2_TX_DESC(intr) BIT((intr) + 14)
#define ASP_INTR2_UMC0_WAKE BIT(22)
#define ASP_INTR2_UMC1_WAKE BIT(28)
#define ASP_INTR2_PHY_EVENT(intr) ((intr) ? BIT(30) | BIT(31) : \
BIT(24) | BIT(25))

#define ASP_WAKEUP_INTR2_OFFSET 0x1200
#define ASP_WAKEUP_INTR2_STATUS 0x0
Expand All @@ -33,6 +35,12 @@
#define ASP_WAKEUP_INTR2_FILT_1 BIT(3)
#define ASP_WAKEUP_INTR2_FW BIT(4)

#define ASP_CTRL2_OFFSET 0x2000
#define ASP_CTRL2_CORE_CLOCK_SELECT 0x0
#define ASP_CTRL2_CORE_CLOCK_SELECT_MAIN BIT(0)
#define ASP_CTRL2_CPU_CLOCK_SELECT 0x4
#define ASP_CTRL2_CPU_CLOCK_SELECT_MAIN BIT(0)

#define ASP_TX_ANALYTICS_OFFSET 0x4c000
#define ASP_TX_ANALYTICS_CTRL 0x0

Expand Down Expand Up @@ -134,8 +142,11 @@ enum asp_rx_net_filter_block {
#define ASP_EDPKT_RX_PKT_CNT 0x138
#define ASP_EDPKT_HDR_EXTR_CNT 0x13c
#define ASP_EDPKT_HDR_OUT_CNT 0x140
#define ASP_EDPKT_SPARE_REG 0x174
#define ASP_EDPKT_SPARE_REG_EPHY_LPI BIT(4)
#define ASP_EDPKT_SPARE_REG_GPHY_LPI BIT(3)

#define ASP_CTRL 0x101000
#define ASP_CTRL_OFFSET 0x101000
#define ASP_CTRL_ASP_SW_INIT 0x04
#define ASP_CTRL_ASP_SW_INIT_ACPUSS_CORE BIT(0)
#define ASP_CTRL_ASP_SW_INIT_ASP_TX BIT(1)
Expand Down Expand Up @@ -306,6 +317,7 @@ struct bcmasp_intf {
struct bcmasp_desc *rx_edpkt_cpu;
dma_addr_t rx_edpkt_dma_addr;
dma_addr_t rx_edpkt_dma_read;
dma_addr_t rx_edpkt_dma_valid;

/* RX buffer prefetcher ring*/
void *rx_ring_cpu;
Expand Down Expand Up @@ -372,6 +384,8 @@ struct bcmasp_plat_data {
void (*init_wol)(struct bcmasp_priv *priv);
void (*enable_wol)(struct bcmasp_intf *intf, bool en);
void (*destroy_wol)(struct bcmasp_priv *priv);
void (*core_clock_select)(struct bcmasp_priv *priv, bool slow);
void (*eee_fixup)(struct bcmasp_intf *priv, bool en);
struct bcmasp_hw_info *hw_info;
};

Expand All @@ -390,6 +404,8 @@ struct bcmasp_priv {
void (*init_wol)(struct bcmasp_priv *priv);
void (*enable_wol)(struct bcmasp_intf *intf, bool en);
void (*destroy_wol)(struct bcmasp_priv *priv);
void (*core_clock_select)(struct bcmasp_priv *priv, bool slow);
void (*eee_fixup)(struct bcmasp_intf *intf, bool en);

void __iomem *base;
struct bcmasp_hw_info *hw_info;
Expand Down Expand Up @@ -530,7 +546,8 @@ BCMASP_CORE_IO_MACRO(rx_analytics, ASP_RX_ANALYTICS_OFFSET);
BCMASP_CORE_IO_MACRO(rx_ctrl, ASP_RX_CTRL_OFFSET);
BCMASP_CORE_IO_MACRO(rx_filter, ASP_RX_FILTER_OFFSET);
BCMASP_CORE_IO_MACRO(rx_edpkt, ASP_EDPKT_OFFSET);
BCMASP_CORE_IO_MACRO(ctrl, ASP_CTRL);
BCMASP_CORE_IO_MACRO(ctrl, ASP_CTRL_OFFSET);
BCMASP_CORE_IO_MACRO(ctrl2, ASP_CTRL2_OFFSET);

struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv,
struct device_node *ndev_dn, int i);
Expand All @@ -541,6 +558,8 @@ void bcmasp_enable_tx_irq(struct bcmasp_intf *intf, int en);

void bcmasp_enable_rx_irq(struct bcmasp_intf *intf, int en);

void bcmasp_enable_phy_irq(struct bcmasp_intf *intf, int en);

void bcmasp_flush_rx_port(struct bcmasp_intf *intf);

extern const struct ethtool_ops bcmasp_ethtool_ops;
Expand Down
Loading

0 comments on commit 7779f26

Please sign in to comment.