]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
net: bcmasp: Add support for ASP 2.2
authorJustin Chen <justin.chen@broadcom.com>
Wed, 28 Feb 2024 22:53:57 +0000 (14:53 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 1 Mar 2024 09:22:49 +0000 (09:22 +0000)
ASP 2.2 improves power savings during low power modes.

A new register was added to toggle to a slower clock during low
power modes.

EEE was broken for ASP 2.0/2.1. A HW workaround was added for
ASP 2.2 that requires toggling a chicken bit.

Signed-off-by: Justin Chen <justin.chen@broadcom.com>
Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/asp2/bcmasp.c
drivers/net/ethernet/broadcom/asp2/bcmasp.h
drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c

index 80245c65cc904defdec4637eb66a9c1edd6eb03f..100c69f3307a3556bfa7d912a80004d83048cc56 100644 (file)
@@ -972,7 +972,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;
 
@@ -1166,6 +1185,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,
@@ -1178,6 +1215,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,
 };
 
@@ -1194,17 +1232,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 */ },
@@ -1265,16 +1325,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);
@@ -1381,7 +1438,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);
 
@@ -1399,7 +1456,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);
index 312bf9b6576efd9df86496b779c1b7c02940d94f..61598dc070b1a05a0a3ec916d64d86a4cc294316 100644 (file)
 #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
 
@@ -134,8 +140,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)
@@ -372,6 +381,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;
 };
 
@@ -390,6 +401,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;
@@ -530,7 +543,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);
index e429876c7291dec3c5a63b469bb9501a28090e7c..36e6fae937ea496012ca3283e4938d1307ea95aa 100644 (file)
@@ -1333,6 +1333,9 @@ static void bcmasp_suspend_to_wol(struct bcmasp_intf *intf)
                                     ASP_WAKEUP_INTR2_MASK_CLEAR);
        }
 
+       if (intf->eee.eee_enabled && intf->parent->eee_fixup)
+               intf->parent->eee_fixup(intf, true);
+
        netif_dbg(intf, wol, ndev, "entered WOL mode\n");
 }
 
@@ -1381,6 +1384,9 @@ static void bcmasp_resume_from_wol(struct bcmasp_intf *intf)
 {
        u32 reg;
 
+       if (intf->eee.eee_enabled && intf->parent->eee_fixup)
+               intf->parent->eee_fixup(intf, false);
+
        reg = umac_rl(intf, UMC_MPD_CTRL);
        reg &= ~UMC_MPD_CTRL_MPD_EN;
        umac_wl(intf, reg, UMC_MPD_CTRL);