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: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2021-08-16 10:30:27 +01:00
commit cbbb7abdd0
3 changed files with 60 additions and 2 deletions

View File

@ -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

View File

@ -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"

View File

@ -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);