[5/9] net: mdio: ipq4019: support MDIO clock frequency divider
Commit Message
The MDIO clock frequency can be divided according to the
register value.
The MDIO system clock is fixed to 100MHZ, the working
frequency is 100MHZ/(divider + 1), the divider value
is from the bit[7:0] of control register 0x40.
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
drivers/net/mdio/mdio-ipq4019.c | 11 +++++++++++
1 file changed, 11 insertions(+)
Comments
> + /* MDIO default frequency is 6.25MHz */
> + priv->clk_div = 0xf;
802.3 says MDC should be 2.5Mhz. Its O.K. to support faster clocks,
but it should be an optional DT property, clock-frequency as described
in the binding.
Andrew
On 11/15/2023 11:22 PM, Andrew Lunn wrote:
>> + /* MDIO default frequency is 6.25MHz */
>> + priv->clk_div = 0xf;
>
> 802.3 says MDC should be 2.5Mhz. Its O.K. to support faster clocks,
> but it should be an optional DT property, clock-frequency as described
> in the binding.
>
> Andrew
Ok, Andrew, will add the DT property "clock-frequency" to support this
clock divider in the next patch set, thanks.
@@ -30,6 +30,9 @@
/* 0 = Clause 22, 1 = Clause 45 */
#define MDIO_MODE_C45 BIT(8)
+/* MDC frequency is SYS_CLK/(MDIO_CLK_DIV + 1), SYS_CLK is 100MHz */
+#define MDIO_CLK_DIV_MASK GENMASK(7, 0)
+
#define IPQ4019_MDIO_TIMEOUT 10000
#define IPQ4019_MDIO_SLEEP 10
@@ -65,6 +68,7 @@ struct ipq4019_mdio_data {
void __iomem *eth_ldo_rdy[ETH_LDO_RDY_CNT];
struct clk *clk[MDIO_CLK_CNT];
struct gpio_descs *reset_gpios;
+ int clk_div;
};
const char *const mdio_clk_name[] = {
@@ -98,6 +102,7 @@ static int ipq4019_mdio_read_c45(struct mii_bus *bus, int mii_id, int mmd,
data = readl(priv->membase + MDIO_MODE_REG);
data |= MDIO_MODE_C45;
+ data |= FIELD_PREP(MDIO_CLK_DIV_MASK, priv->clk_div);
writel(data, priv->membase + MDIO_MODE_REG);
@@ -139,6 +144,7 @@ static int ipq4019_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
data = readl(priv->membase + MDIO_MODE_REG);
data &= ~MDIO_MODE_C45;
+ data |= FIELD_PREP(MDIO_CLK_DIV_MASK, priv->clk_div);
writel(data, priv->membase + MDIO_MODE_REG);
@@ -171,6 +177,7 @@ static int ipq4019_mdio_write_c45(struct mii_bus *bus, int mii_id, int mmd,
data = readl(priv->membase + MDIO_MODE_REG);
data |= MDIO_MODE_C45;
+ data |= FIELD_PREP(MDIO_CLK_DIV_MASK, priv->clk_div);
writel(data, priv->membase + MDIO_MODE_REG);
@@ -214,6 +221,7 @@ static int ipq4019_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
data = readl(priv->membase + MDIO_MODE_REG);
data &= ~MDIO_MODE_C45;
+ data |= FIELD_PREP(MDIO_CLK_DIV_MASK, priv->clk_div);
writel(data, priv->membase + MDIO_MODE_REG);
@@ -431,6 +439,9 @@ static int ipq4019_mdio_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(priv->reset_gpios),
"mii_bus %s couldn't get reset GPIO\n", bus->id);
+ /* MDIO default frequency is 6.25MHz */
+ priv->clk_div = 0xf;
+
bus->name = "ipq4019_mdio";
bus->read = ipq4019_mdio_read_c22;
bus->write = ipq4019_mdio_write_c22;