Commit 189dd626 authored by Thomas Petazzoni's avatar Thomas Petazzoni

net: mvneta: add clk support

Now that the Armada 370/XP platform has gained proper integration with
the clock framework, we add clk support in the Marvell Armada 370/XP
Ethernet driver.

Since the existing Device Tree binding that exposes a
'clock-frequency' property has never been exposed in any stable kernel
release, we take the freedom of removing this property to replace it
with the standard 'clocks' clock pointer property.

The Device Tree binding documentation is updated accordingly.
Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
parent 6a20c175
...@@ -8,7 +8,7 @@ Required properties: ...@@ -8,7 +8,7 @@ Required properties:
property, a single integer). property, a single integer).
- phy-mode: The interface between the SoC and the PHY (a string that - phy-mode: The interface between the SoC and the PHY (a string that
of_get_phy_mode() can understand) of_get_phy_mode() can understand)
- clock-frequency: frequency of the peripheral clock of the SoC. - clocks: a pointer to the reference clock for this device.
Example: Example:
...@@ -16,7 +16,7 @@ ethernet@d0070000 { ...@@ -16,7 +16,7 @@ ethernet@d0070000 {
compatible = "marvell,armada-370-neta"; compatible = "marvell,armada-370-neta";
reg = <0xd0070000 0x2500>; reg = <0xd0070000 0x2500>;
interrupts = <8>; interrupts = <8>;
clock-frequency = <250000000>; clocks = <&gate_clk 4>;
status = "okay"; status = "okay";
phy = <&phy0>; phy = <&phy0>;
phy-mode = "rgmii-id"; phy-mode = "rgmii-id";
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/clk.h>
/* Registers */ /* Registers */
#define MVNETA_RXQ_CONFIG_REG(q) (0x1400 + ((q) << 2)) #define MVNETA_RXQ_CONFIG_REG(q) (0x1400 + ((q) << 2))
...@@ -242,7 +243,7 @@ struct mvneta_port { ...@@ -242,7 +243,7 @@ struct mvneta_port {
int weight; int weight;
/* Core clock */ /* Core clock */
unsigned int clk_rate_hz; struct clk *clk;
u8 mcast_count[256]; u8 mcast_count[256];
u16 tx_ring_size; u16 tx_ring_size;
u16 rx_ring_size; u16 rx_ring_size;
...@@ -1029,7 +1030,11 @@ static void mvneta_rx_pkts_coal_set(struct mvneta_port *pp, ...@@ -1029,7 +1030,11 @@ static void mvneta_rx_pkts_coal_set(struct mvneta_port *pp,
static void mvneta_rx_time_coal_set(struct mvneta_port *pp, static void mvneta_rx_time_coal_set(struct mvneta_port *pp,
struct mvneta_rx_queue *rxq, u32 value) struct mvneta_rx_queue *rxq, u32 value)
{ {
u32 val = (pp->clk_rate_hz / 1000000) * value; u32 val;
unsigned long clk_rate;
clk_rate = clk_get_rate(pp->clk);
val = (clk_rate / 1000000) * value;
mvreg_write(pp, MVNETA_RXQ_TIME_COAL_REG(rxq->id), val); mvreg_write(pp, MVNETA_RXQ_TIME_COAL_REG(rxq->id), val);
rxq->time_coal = value; rxq->time_coal = value;
...@@ -2671,7 +2676,7 @@ static int __devinit mvneta_probe(struct platform_device *pdev) ...@@ -2671,7 +2676,7 @@ static int __devinit mvneta_probe(struct platform_device *pdev)
const struct mbus_dram_target_info *dram_target_info; const struct mbus_dram_target_info *dram_target_info;
struct device_node *dn = pdev->dev.of_node; struct device_node *dn = pdev->dev.of_node;
struct device_node *phy_node; struct device_node *phy_node;
u32 phy_addr, clk_rate_hz; u32 phy_addr;
struct mvneta_port *pp; struct mvneta_port *pp;
struct net_device *dev; struct net_device *dev;
const char *mac_addr; const char *mac_addr;
...@@ -2710,12 +2715,6 @@ static int __devinit mvneta_probe(struct platform_device *pdev) ...@@ -2710,12 +2715,6 @@ static int __devinit mvneta_probe(struct platform_device *pdev)
goto err_free_irq; goto err_free_irq;
} }
if (of_property_read_u32(dn, "clock-frequency", &clk_rate_hz) != 0) {
dev_err(&pdev->dev, "could not read clock-frequency\n");
err = -EINVAL;
goto err_free_irq;
}
mac_addr = of_get_mac_address(dn); mac_addr = of_get_mac_address(dn);
if (!mac_addr || !is_valid_ether_addr(mac_addr)) if (!mac_addr || !is_valid_ether_addr(mac_addr))
...@@ -2736,7 +2735,6 @@ static int __devinit mvneta_probe(struct platform_device *pdev) ...@@ -2736,7 +2735,6 @@ static int __devinit mvneta_probe(struct platform_device *pdev)
clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags); clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
pp->weight = MVNETA_RX_POLL_WEIGHT; pp->weight = MVNETA_RX_POLL_WEIGHT;
pp->clk_rate_hz = clk_rate_hz;
pp->phy_node = phy_node; pp->phy_node = phy_node;
pp->phy_interface = phy_mode; pp->phy_interface = phy_mode;
...@@ -2746,6 +2744,14 @@ static int __devinit mvneta_probe(struct platform_device *pdev) ...@@ -2746,6 +2744,14 @@ static int __devinit mvneta_probe(struct platform_device *pdev)
goto err_free_irq; goto err_free_irq;
} }
pp->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pp->clk)) {
err = PTR_ERR(pp->clk);
goto err_unmap;
}
clk_prepare_enable(pp->clk);
pp->tx_done_timer.data = (unsigned long)dev; pp->tx_done_timer.data = (unsigned long)dev;
pp->tx_ring_size = MVNETA_MAX_TXD; pp->tx_ring_size = MVNETA_MAX_TXD;
...@@ -2757,7 +2763,7 @@ static int __devinit mvneta_probe(struct platform_device *pdev) ...@@ -2757,7 +2763,7 @@ static int __devinit mvneta_probe(struct platform_device *pdev)
err = mvneta_init(pp, phy_addr); err = mvneta_init(pp, phy_addr);
if (err < 0) { if (err < 0) {
dev_err(&pdev->dev, "can't init eth hal\n"); dev_err(&pdev->dev, "can't init eth hal\n");
goto err_unmap; goto err_clk;
} }
mvneta_port_power_up(pp, phy_mode); mvneta_port_power_up(pp, phy_mode);
...@@ -2785,6 +2791,8 @@ static int __devinit mvneta_probe(struct platform_device *pdev) ...@@ -2785,6 +2791,8 @@ static int __devinit mvneta_probe(struct platform_device *pdev)
err_deinit: err_deinit:
mvneta_deinit(pp); mvneta_deinit(pp);
err_clk:
clk_disable_unprepare(pp->clk);
err_unmap: err_unmap:
iounmap(pp->base); iounmap(pp->base);
err_free_irq: err_free_irq:
...@@ -2802,6 +2810,7 @@ static int __devexit mvneta_remove(struct platform_device *pdev) ...@@ -2802,6 +2810,7 @@ static int __devexit mvneta_remove(struct platform_device *pdev)
unregister_netdev(dev); unregister_netdev(dev);
mvneta_deinit(pp); mvneta_deinit(pp);
clk_disable_unprepare(pp->clk);
iounmap(pp->base); iounmap(pp->base);
irq_dispose_mapping(dev->irq); irq_dispose_mapping(dev->irq);
free_netdev(dev); free_netdev(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment