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

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
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -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>;
+6 −2
Original line number Diff line number Diff line
@@ -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;
+27 −7
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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;