|
@@ -21,6 +21,7 @@
|
|
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
|
|
+#include <linux/clk.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
|
#include <linux/etherdevice.h>
|
|
|
#include <linux/ethtool.h>
|
|
@@ -59,6 +60,9 @@
|
|
|
/* Min number of tx ring entries before stopping queue */
|
|
|
#define TX_THRESHOLD (MAX_SKB_FRAGS + 1)
|
|
|
|
|
|
+#define FTGMAC_100MHZ 100000000
|
|
|
+#define FTGMAC_25MHZ 25000000
|
|
|
+
|
|
|
struct ftgmac100 {
|
|
|
/* Registers */
|
|
|
struct resource *res;
|
|
@@ -96,6 +100,7 @@ struct ftgmac100 {
|
|
|
struct napi_struct napi;
|
|
|
struct work_struct reset_task;
|
|
|
struct mii_bus *mii_bus;
|
|
|
+ struct clk *clk;
|
|
|
|
|
|
/* Link management */
|
|
|
int cur_speed;
|
|
@@ -1734,6 +1739,22 @@ static void ftgmac100_ncsi_handler(struct ncsi_dev *nd)
|
|
|
nd->link_up ? "up" : "down");
|
|
|
}
|
|
|
|
|
|
+static void ftgmac100_setup_clk(struct ftgmac100 *priv)
|
|
|
+{
|
|
|
+ priv->clk = devm_clk_get(priv->dev, NULL);
|
|
|
+ if (IS_ERR(priv->clk))
|
|
|
+ return;
|
|
|
+
|
|
|
+ clk_prepare_enable(priv->clk);
|
|
|
+
|
|
|
+ /* Aspeed specifies a 100MHz clock is required for up to
|
|
|
+ * 1000Mbit link speeds. As NCSI is limited to 100Mbit, 25MHz
|
|
|
+ * is sufficient
|
|
|
+ */
|
|
|
+ clk_set_rate(priv->clk, priv->use_ncsi ? FTGMAC_25MHZ :
|
|
|
+ FTGMAC_100MHZ);
|
|
|
+}
|
|
|
+
|
|
|
static int ftgmac100_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct resource *res;
|
|
@@ -1830,6 +1851,9 @@ static int ftgmac100_probe(struct platform_device *pdev)
|
|
|
goto err_setup_mdio;
|
|
|
}
|
|
|
|
|
|
+ if (priv->is_aspeed)
|
|
|
+ ftgmac100_setup_clk(priv);
|
|
|
+
|
|
|
/* Default ring sizes */
|
|
|
priv->rx_q_entries = priv->new_rx_q_entries = DEF_RX_QUEUE_ENTRIES;
|
|
|
priv->tx_q_entries = priv->new_tx_q_entries = DEF_TX_QUEUE_ENTRIES;
|
|
@@ -1883,6 +1907,8 @@ static int ftgmac100_remove(struct platform_device *pdev)
|
|
|
|
|
|
unregister_netdev(netdev);
|
|
|
|
|
|
+ clk_disable_unprepare(priv->clk);
|
|
|
+
|
|
|
/* There's a small chance the reset task will have been re-queued,
|
|
|
* during stop, make sure it's gone before we free the structure.
|
|
|
*/
|