Commit 4e6d698f authored by David S. Miller's avatar David S. Miller

Merge branch 'axienet-clock-additions'

Robert Hancock says:

====================
axienet clock additions

Add support to the axienet driver for controlling all of the clocks that
the logic core may utilize.

Changed since v3:
-Added Acked-by to patch 1
-Now applies to net-next tree after earlier patches merged in - code
unchanged from v3

Changed since v2:
-Additional clock description clarification

Changed since v1:
-Clarified clock usages in documentation and code comments
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 32bc7a2c b11bfb9a
......@@ -42,11 +42,23 @@ Optional properties:
support both 1000BaseX and SGMII modes. If set, the phy-mode
should be set to match the mode selected on core reset (i.e.
by the basex_or_sgmii core input line).
- clocks : AXI bus clock for the device. Refer to common clock bindings.
Used to calculate MDIO clock divisor. If not specified, it is
auto-detected from the CPU clock (but only on platforms where
this is possible). New device trees should specify this - the
auto detection is only for backward compatibility.
- clock-names: Tuple listing input clock names. Possible clocks:
s_axi_lite_clk: Clock for AXI register slave interface
axis_clk: AXI4-Stream clock for TXD RXD TXC and RXS interfaces
ref_clk: Ethernet reference clock, used by signal delay
primitives and transceivers
mgt_clk: MGT reference clock (used by optional internal
PCS/PMA PHY)
Note that if s_axi_lite_clk is not specified by name, the
first clock of any name is used for this. If that is also not
specified, the clock rate is auto-detected from the CPU clock
(but only on platforms where this is possible). New device
trees should specify all applicable clocks by name - the
fallbacks to an unnamed clock or to CPU clock are only for
backward compatibility.
- clocks: Phandles to input clocks matching clock-names. Refer to common
clock bindings.
- axistream-connected: Reference to another node which contains the resources
for the AXI DMA controller used by this device.
If this is specified, the DMA-related resources from that
......@@ -62,7 +74,8 @@ Example:
device_type = "network";
interrupt-parent = <&microblaze_0_axi_intc>;
interrupts = <2 0 1>;
clocks = <&axi_clk>;
clock-names = "s_axi_lite_clk", "axis_clk", "ref_clk", "mgt_clk";
clocks = <&axi_clk>, <&axi_clk>, <&pl_enet_ref_clk>, <&mgt_clk>;
phy-mode = "mii";
reg = <0x40c00000 0x40000 0x50c00000 0x40000>;
xlnx,rxcsum = <0x2>;
......
......@@ -376,6 +376,8 @@ struct axidma_bd {
struct sk_buff *skb;
} __aligned(XAXIDMA_BD_MINIMUM_ALIGNMENT);
#define XAE_NUM_MISC_CLOCKS 3
/**
* struct axienet_local - axienet private per device data
* @ndev: Pointer for net_device to which it will be attached.
......@@ -385,7 +387,8 @@ struct axidma_bd {
* @phylink_config: phylink configuration settings
* @pcs_phy: Reference to PCS/PMA PHY if used
* @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core
* @clk: Clock for AXI bus
* @axi_clk: AXI4-Lite bus clock
* @misc_clks: Misc ethernet clocks (AXI4-Stream, Ref, MGT clocks)
* @mii_bus: Pointer to MII bus structure
* @mii_clk_div: MII bus clock divider value
* @regs_start: Resource start for axienet device addresses
......@@ -434,7 +437,8 @@ struct axienet_local {
bool switch_x_sgmii;
struct clk *clk;
struct clk *axi_clk;
struct clk_bulk_data misc_clks[XAE_NUM_MISC_CLOCKS];
struct mii_bus *mii_bus;
u8 mii_clk_div;
......
......@@ -1863,17 +1863,35 @@ static int axienet_probe(struct platform_device *pdev)
lp->rx_bd_num = RX_BD_NUM_DEFAULT;
lp->tx_bd_num = TX_BD_NUM_DEFAULT;
lp->clk = devm_clk_get_optional(&pdev->dev, NULL);
if (IS_ERR(lp->clk)) {
ret = PTR_ERR(lp->clk);
lp->axi_clk = devm_clk_get_optional(&pdev->dev, "s_axi_lite_clk");
if (!lp->axi_clk) {
/* For backward compatibility, if named AXI clock is not present,
* treat the first clock specified as the AXI clock.
*/
lp->axi_clk = devm_clk_get_optional(&pdev->dev, NULL);
}
if (IS_ERR(lp->axi_clk)) {
ret = PTR_ERR(lp->axi_clk);
goto free_netdev;
}
ret = clk_prepare_enable(lp->clk);
ret = clk_prepare_enable(lp->axi_clk);
if (ret) {
dev_err(&pdev->dev, "Unable to enable clock: %d\n", ret);
dev_err(&pdev->dev, "Unable to enable AXI clock: %d\n", ret);
goto free_netdev;
}
lp->misc_clks[0].id = "axis_clk";
lp->misc_clks[1].id = "ref_clk";
lp->misc_clks[2].id = "mgt_clk";
ret = devm_clk_bulk_get_optional(&pdev->dev, XAE_NUM_MISC_CLOCKS, lp->misc_clks);
if (ret)
goto cleanup_clk;
ret = clk_bulk_prepare_enable(XAE_NUM_MISC_CLOCKS, lp->misc_clks);
if (ret)
goto cleanup_clk;
/* Map device registers */
ethres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lp->regs = devm_ioremap_resource(&pdev->dev, ethres);
......@@ -2109,7 +2127,8 @@ static int axienet_probe(struct platform_device *pdev)
of_node_put(lp->phy_node);
cleanup_clk:
clk_disable_unprepare(lp->clk);
clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, lp->misc_clks);
clk_disable_unprepare(lp->axi_clk);
free_netdev:
free_netdev(ndev);
......@@ -2132,7 +2151,8 @@ static int axienet_remove(struct platform_device *pdev)
axienet_mdio_teardown(lp);
clk_disable_unprepare(lp->clk);
clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, lp->misc_clks);
clk_disable_unprepare(lp->axi_clk);
of_node_put(lp->phy_node);
lp->phy_node = NULL;
......
......@@ -159,8 +159,8 @@ int axienet_mdio_enable(struct axienet_local *lp)
lp->mii_clk_div = 0;
if (lp->clk) {
host_clock = clk_get_rate(lp->clk);
if (lp->axi_clk) {
host_clock = clk_get_rate(lp->axi_clk);
} else {
struct device_node *np1;
......
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