ARM: Orion: Eth: Add clk/clkdev support.
The t_clk is moved from the shared part of the ethernet driver into the per port section. Each port can have its own gated clock, which it needs to enable/disable, as oppossed to there being one clock shared by all ports. In practice, only kirkwood supports this at the moment. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Jamie Lentin <jm@lentin.co.uk> Signed-off-by: Mike Turquette <mturquette@linaro.org>
This commit is contained in:

committed by
Mike Turquette

parent
4574b88669
commit
452503ebc7
@@ -57,6 +57,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/inet_lro.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
|
||||
static char mv643xx_eth_driver_version[] = "1.4";
|
||||
@@ -289,10 +290,10 @@ struct mv643xx_eth_shared_private {
|
||||
/*
|
||||
* Hardware-specific parameters.
|
||||
*/
|
||||
unsigned int t_clk;
|
||||
int extended_rx_coal_limit;
|
||||
int tx_bw_control;
|
||||
int tx_csum_limit;
|
||||
|
||||
};
|
||||
|
||||
#define TX_BW_CONTROL_ABSENT 0
|
||||
@@ -431,6 +432,12 @@ struct mv643xx_eth_private {
|
||||
int tx_desc_sram_size;
|
||||
int txq_count;
|
||||
struct tx_queue txq[8];
|
||||
|
||||
/*
|
||||
* Hardware-specific parameters.
|
||||
*/
|
||||
struct clk *clk;
|
||||
unsigned int t_clk;
|
||||
};
|
||||
|
||||
|
||||
@@ -1010,7 +1017,7 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst)
|
||||
int mtu;
|
||||
int bucket_size;
|
||||
|
||||
token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000);
|
||||
token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000);
|
||||
if (token_rate > 1023)
|
||||
token_rate = 1023;
|
||||
|
||||
@@ -1042,7 +1049,7 @@ static void txq_set_rate(struct tx_queue *txq, int rate, int burst)
|
||||
int token_rate;
|
||||
int bucket_size;
|
||||
|
||||
token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000);
|
||||
token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000);
|
||||
if (token_rate > 1023)
|
||||
token_rate = 1023;
|
||||
|
||||
@@ -1309,7 +1316,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp)
|
||||
temp = (val & 0x003fff00) >> 8;
|
||||
|
||||
temp *= 64000000;
|
||||
do_div(temp, mp->shared->t_clk);
|
||||
do_div(temp, mp->t_clk);
|
||||
|
||||
return (unsigned int)temp;
|
||||
}
|
||||
@@ -1319,7 +1326,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
|
||||
u64 temp;
|
||||
u32 val;
|
||||
|
||||
temp = (u64)usec * mp->shared->t_clk;
|
||||
temp = (u64)usec * mp->t_clk;
|
||||
temp += 31999999;
|
||||
do_div(temp, 64000000);
|
||||
|
||||
@@ -1345,7 +1352,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp)
|
||||
|
||||
temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4;
|
||||
temp *= 64000000;
|
||||
do_div(temp, mp->shared->t_clk);
|
||||
do_div(temp, mp->t_clk);
|
||||
|
||||
return (unsigned int)temp;
|
||||
}
|
||||
@@ -1354,7 +1361,7 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
|
||||
{
|
||||
u64 temp;
|
||||
|
||||
temp = (u64)usec * mp->shared->t_clk;
|
||||
temp = (u64)usec * mp->t_clk;
|
||||
temp += 31999999;
|
||||
do_div(temp, 64000000);
|
||||
|
||||
@@ -2662,10 +2669,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
|
||||
if (dram)
|
||||
mv643xx_eth_conf_mbus_windows(msp, dram);
|
||||
|
||||
/*
|
||||
* Detect hardware parameters.
|
||||
*/
|
||||
msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000;
|
||||
msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?
|
||||
pd->tx_csum_limit : 9 * 1024;
|
||||
infer_hw_params(msp);
|
||||
@@ -2890,6 +2893,18 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
||||
|
||||
mp->dev = dev;
|
||||
|
||||
/*
|
||||
* Get the clk rate, if there is one, otherwise use the default.
|
||||
*/
|
||||
mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0"));
|
||||
if (!IS_ERR(mp->clk)) {
|
||||
clk_prepare_enable(mp->clk);
|
||||
mp->t_clk = clk_get_rate(mp->clk);
|
||||
} else {
|
||||
mp->t_clk = 133000000;
|
||||
printk(KERN_WARNING "Unable to get clock");
|
||||
}
|
||||
|
||||
set_params(mp, pd);
|
||||
netif_set_real_num_tx_queues(dev, mp->txq_count);
|
||||
netif_set_real_num_rx_queues(dev, mp->rxq_count);
|
||||
@@ -2978,6 +2993,11 @@ static int mv643xx_eth_remove(struct platform_device *pdev)
|
||||
if (mp->phy != NULL)
|
||||
phy_detach(mp->phy);
|
||||
cancel_work_sync(&mp->tx_timeout_task);
|
||||
|
||||
if (!IS_ERR(mp->clk)) {
|
||||
clk_disable_unprepare(mp->clk);
|
||||
clk_put(mp->clk);
|
||||
}
|
||||
free_netdev(mp->dev);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
Reference in New Issue
Block a user