diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-05-16 10:35:25 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-05-16 10:35:25 -0400 |
commit | 3c0dec5f58b3c7b3627715126d1bf9b030a076f0 (patch) | |
tree | 4bf8f56fca3bf6be109209b116fc8e32cb2e0f9e /drivers/net/ethernet/marvell | |
parent | fcd8d84a585f3578a9ebdd27e757495a27415322 (diff) | |
parent | 7e0fa1b5fa91d9aa456d102c273b2cf0f2e95d39 (diff) |
Merge branch 'clk-next' of git://git.linaro.org/people/mturquette/linux into next/clock
* 'clk-next' of git://git.linaro.org/people/mturquette/linux:
clk: Fix CLK_SET_RATE_GATE flag validation in clk_set_rate().
clk: Provide dummy clk_unregister()
ARM: Kirkwood: Replace clock gating
ARM: Orion: Audio: Add clk/clkdev support
ARM: Orion: PCIE: Add support for clk
ARM: Orion: XOR: Add support for clk
ARM: Orion: CESA: Add support for clk
ARM: Orion: SDIO: Add support for clk.
ARM: Orion: NAND: Add support for clk, if there is one.
ARM: Orion: EHCI: Add support for enabling clocks
ARM: Orion: SATA: Add per channel clk/clkdev support.
ARM: Orion: UART: Get the clock rate via clk_get_rate().
ARM: Orion: WDT: Add clk/clkdev support
ARM: Orion: Eth: Add clk/clkdev support.
ARM: Orion: SPI: Add clk/clkdev support.
ARM: Orion: Add clocks using the generic clk infrastructure.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/net/ethernet/marvell')
-rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 5e1ca0f05090..99cd233266ac 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/types.h> | 57 | #include <linux/types.h> |
58 | #include <linux/inet_lro.h> | 58 | #include <linux/inet_lro.h> |
59 | #include <linux/slab.h> | 59 | #include <linux/slab.h> |
60 | #include <linux/clk.h> | ||
60 | 61 | ||
61 | static char mv643xx_eth_driver_name[] = "mv643xx_eth"; | 62 | static char mv643xx_eth_driver_name[] = "mv643xx_eth"; |
62 | static char mv643xx_eth_driver_version[] = "1.4"; | 63 | static char mv643xx_eth_driver_version[] = "1.4"; |
@@ -289,10 +290,10 @@ struct mv643xx_eth_shared_private { | |||
289 | /* | 290 | /* |
290 | * Hardware-specific parameters. | 291 | * Hardware-specific parameters. |
291 | */ | 292 | */ |
292 | unsigned int t_clk; | ||
293 | int extended_rx_coal_limit; | 293 | int extended_rx_coal_limit; |
294 | int tx_bw_control; | 294 | int tx_bw_control; |
295 | int tx_csum_limit; | 295 | int tx_csum_limit; |
296 | |||
296 | }; | 297 | }; |
297 | 298 | ||
298 | #define TX_BW_CONTROL_ABSENT 0 | 299 | #define TX_BW_CONTROL_ABSENT 0 |
@@ -431,6 +432,12 @@ struct mv643xx_eth_private { | |||
431 | int tx_desc_sram_size; | 432 | int tx_desc_sram_size; |
432 | int txq_count; | 433 | int txq_count; |
433 | struct tx_queue txq[8]; | 434 | struct tx_queue txq[8]; |
435 | |||
436 | /* | ||
437 | * Hardware-specific parameters. | ||
438 | */ | ||
439 | struct clk *clk; | ||
440 | unsigned int t_clk; | ||
434 | }; | 441 | }; |
435 | 442 | ||
436 | 443 | ||
@@ -1010,7 +1017,7 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst) | |||
1010 | int mtu; | 1017 | int mtu; |
1011 | int bucket_size; | 1018 | int bucket_size; |
1012 | 1019 | ||
1013 | token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); | 1020 | token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); |
1014 | if (token_rate > 1023) | 1021 | if (token_rate > 1023) |
1015 | token_rate = 1023; | 1022 | token_rate = 1023; |
1016 | 1023 | ||
@@ -1042,7 +1049,7 @@ static void txq_set_rate(struct tx_queue *txq, int rate, int burst) | |||
1042 | int token_rate; | 1049 | int token_rate; |
1043 | int bucket_size; | 1050 | int bucket_size; |
1044 | 1051 | ||
1045 | token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); | 1052 | token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); |
1046 | if (token_rate > 1023) | 1053 | if (token_rate > 1023) |
1047 | token_rate = 1023; | 1054 | token_rate = 1023; |
1048 | 1055 | ||
@@ -1309,7 +1316,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp) | |||
1309 | temp = (val & 0x003fff00) >> 8; | 1316 | temp = (val & 0x003fff00) >> 8; |
1310 | 1317 | ||
1311 | temp *= 64000000; | 1318 | temp *= 64000000; |
1312 | do_div(temp, mp->shared->t_clk); | 1319 | do_div(temp, mp->t_clk); |
1313 | 1320 | ||
1314 | return (unsigned int)temp; | 1321 | return (unsigned int)temp; |
1315 | } | 1322 | } |
@@ -1319,7 +1326,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec) | |||
1319 | u64 temp; | 1326 | u64 temp; |
1320 | u32 val; | 1327 | u32 val; |
1321 | 1328 | ||
1322 | temp = (u64)usec * mp->shared->t_clk; | 1329 | temp = (u64)usec * mp->t_clk; |
1323 | temp += 31999999; | 1330 | temp += 31999999; |
1324 | do_div(temp, 64000000); | 1331 | do_div(temp, 64000000); |
1325 | 1332 | ||
@@ -1345,7 +1352,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp) | |||
1345 | 1352 | ||
1346 | temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; | 1353 | temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; |
1347 | temp *= 64000000; | 1354 | temp *= 64000000; |
1348 | do_div(temp, mp->shared->t_clk); | 1355 | do_div(temp, mp->t_clk); |
1349 | 1356 | ||
1350 | return (unsigned int)temp; | 1357 | return (unsigned int)temp; |
1351 | } | 1358 | } |
@@ -1354,7 +1361,7 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec) | |||
1354 | { | 1361 | { |
1355 | u64 temp; | 1362 | u64 temp; |
1356 | 1363 | ||
1357 | temp = (u64)usec * mp->shared->t_clk; | 1364 | temp = (u64)usec * mp->t_clk; |
1358 | temp += 31999999; | 1365 | temp += 31999999; |
1359 | do_div(temp, 64000000); | 1366 | do_div(temp, 64000000); |
1360 | 1367 | ||
@@ -2662,10 +2669,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) | |||
2662 | if (dram) | 2669 | if (dram) |
2663 | mv643xx_eth_conf_mbus_windows(msp, dram); | 2670 | mv643xx_eth_conf_mbus_windows(msp, dram); |
2664 | 2671 | ||
2665 | /* | ||
2666 | * Detect hardware parameters. | ||
2667 | */ | ||
2668 | msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; | ||
2669 | msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? | 2672 | msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? |
2670 | pd->tx_csum_limit : 9 * 1024; | 2673 | pd->tx_csum_limit : 9 * 1024; |
2671 | infer_hw_params(msp); | 2674 | infer_hw_params(msp); |
@@ -2890,6 +2893,18 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
2890 | 2893 | ||
2891 | mp->dev = dev; | 2894 | mp->dev = dev; |
2892 | 2895 | ||
2896 | /* | ||
2897 | * Get the clk rate, if there is one, otherwise use the default. | ||
2898 | */ | ||
2899 | mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0")); | ||
2900 | if (!IS_ERR(mp->clk)) { | ||
2901 | clk_prepare_enable(mp->clk); | ||
2902 | mp->t_clk = clk_get_rate(mp->clk); | ||
2903 | } else { | ||
2904 | mp->t_clk = 133000000; | ||
2905 | printk(KERN_WARNING "Unable to get clock"); | ||
2906 | } | ||
2907 | |||
2893 | set_params(mp, pd); | 2908 | set_params(mp, pd); |
2894 | netif_set_real_num_tx_queues(dev, mp->txq_count); | 2909 | netif_set_real_num_tx_queues(dev, mp->txq_count); |
2895 | netif_set_real_num_rx_queues(dev, mp->rxq_count); | 2910 | netif_set_real_num_rx_queues(dev, mp->rxq_count); |
@@ -2978,6 +2993,11 @@ static int mv643xx_eth_remove(struct platform_device *pdev) | |||
2978 | if (mp->phy != NULL) | 2993 | if (mp->phy != NULL) |
2979 | phy_detach(mp->phy); | 2994 | phy_detach(mp->phy); |
2980 | cancel_work_sync(&mp->tx_timeout_task); | 2995 | cancel_work_sync(&mp->tx_timeout_task); |
2996 | |||
2997 | if (!IS_ERR(mp->clk)) { | ||
2998 | clk_disable_unprepare(mp->clk); | ||
2999 | clk_put(mp->clk); | ||
3000 | } | ||
2981 | free_netdev(mp->dev); | 3001 | free_netdev(mp->dev); |
2982 | 3002 | ||
2983 | platform_set_drvdata(pdev, NULL); | 3003 | platform_set_drvdata(pdev, NULL); |