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

Merge branch 'ipq-mdio'



Luo Jie says:

====================
net: mdio: Add IPQ MDIO reset related function

This patch series add the MDIO reset features, which includes
configuring MDIO clock source frequency and indicating CMN_PLL that
ethernet LDO has been ready, this ethernet LDO is dedicated in the
IPQ5018 platform.

Specify more chipset IPQ40xx, IPQ807x, IPQ60xx and IPQ50xx supported by
this MDIO driver.

Changes in v3:
	* simplify the function ipq_mdio_reset.

Changes in v2:
	* Addressed review comments (Andrew Lunn).
	* Remove the IS_ERR().
	* make binding patch part of series.
	* document the property 'reg' and 'clock'.

Changes in v1:
	* make MDIO_IPQ4019 unchanged for backwards compatibility.
	* remove the PHY reset functions
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e4637f62 2a4c32e7
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -14,7 +14,9 @@ allOf:

properties:
  compatible:
    const: qcom,ipq4019-mdio
    enum:
      - qcom,ipq4019-mdio
      - qcom,ipq5018-mdio

  "#address-cells":
    const: 1
@@ -23,7 +25,18 @@ properties:
    const: 0

  reg:
    minItems: 1
    maxItems: 2
    description:
      the first Address and length of the register set for the MDIO controller.
      the second Address and length of the register for ethernet LDO, this second
      address range is only required by the platform IPQ50xx.

  clocks:
    maxItems: 1
    description: |
      MDIO clock source frequency fixed to 100MHZ, this clock should be specified
      by the platform IPQ807x, IPQ60xx and IPQ50xx.

required:
  - compatible
+2 −1
Original line number Diff line number Diff line
@@ -169,9 +169,10 @@ config MDIO_OCTEON
config MDIO_IPQ4019
	tristate "Qualcomm IPQ4019 MDIO interface support"
	depends on HAS_IOMEM && OF_MDIO
	depends on COMMON_CLK
	help
	  This driver supports the MDIO interface found in Qualcomm
	  IPQ40xx series Soc-s.
	  IPQ40xx, IPQ60xx, IPQ807x and IPQ50xx series Soc-s.

config MDIO_IPQ8064
	tristate "Qualcomm IPQ8064 MDIO interface support"
+44 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/of_mdio.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/clk.h>

#define MDIO_MODE_REG				0x40
#define MDIO_ADDR_REG				0x44
@@ -31,8 +32,15 @@
#define IPQ4019_MDIO_TIMEOUT	10000
#define IPQ4019_MDIO_SLEEP		10

/* MDIO clock source frequency is fixed to 100M */
#define IPQ_MDIO_CLK_RATE	100000000

#define IPQ_PHY_SET_DELAY_US	100000

struct ipq4019_mdio_data {
	void __iomem	*membase;
	void __iomem *eth_ldo_rdy;
	struct clk *mdio_clk;
};

static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
@@ -171,10 +179,35 @@ static int ipq4019_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
	return 0;
}

static int ipq_mdio_reset(struct mii_bus *bus)
{
	struct ipq4019_mdio_data *priv = bus->priv;
	u32 val;
	int ret;

	/* To indicate CMN_PLL that ethernet_ldo has been ready if platform resource 1
	 * is specified in the device tree.
	 */
	if (priv->eth_ldo_rdy) {
		val = readl(priv->eth_ldo_rdy);
		val |= BIT(0);
		writel(val, priv->eth_ldo_rdy);
		fsleep(IPQ_PHY_SET_DELAY_US);
	}

	/* Configure MDIO clock source frequency if clock is specified in the device tree */
	ret = clk_set_rate(priv->mdio_clk, IPQ_MDIO_CLK_RATE);
	if (ret)
		return ret;

	return clk_prepare_enable(priv->mdio_clk);
}

static int ipq4019_mdio_probe(struct platform_device *pdev)
{
	struct ipq4019_mdio_data *priv;
	struct mii_bus *bus;
	struct resource *res;
	int ret;

	bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv));
@@ -187,9 +220,19 @@ static int ipq4019_mdio_probe(struct platform_device *pdev)
	if (IS_ERR(priv->membase))
		return PTR_ERR(priv->membase);

	priv->mdio_clk = devm_clk_get_optional(&pdev->dev, "gcc_mdio_ahb_clk");
	if (IS_ERR(priv->mdio_clk))
		return PTR_ERR(priv->mdio_clk);

	/* The platform resource is provided on the chipset IPQ5018 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (res)
		priv->eth_ldo_rdy = devm_ioremap_resource(&pdev->dev, res);

	bus->name = "ipq4019_mdio";
	bus->read = ipq4019_mdio_read;
	bus->write = ipq4019_mdio_write;
	bus->reset = ipq_mdio_reset;
	bus->parent = &pdev->dev;
	snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id);

@@ -215,6 +258,7 @@ static int ipq4019_mdio_remove(struct platform_device *pdev)

static const struct of_device_id ipq4019_mdio_dt_ids[] = {
	{ .compatible = "qcom,ipq4019-mdio" },
	{ .compatible = "qcom,ipq5018-mdio" },
	{ }
};
MODULE_DEVICE_TABLE(of, ipq4019_mdio_dt_ids);