mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-29 09:22:53 -04:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -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 = <µblaze_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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user