2 * pic32_mdio.c: PIC32 MDIO/MII driver, part of pic32_eth.c.
4 * Copyright 2015 Microchip Inc.
5 * Purna Chandra Mandal <purna.mandal@microchip.com>
7 * SPDX-License-Identifier: GPL-2.0+
15 #include "pic32_eth.h"
17 static int pic32_mdio_write(struct mii_dev *bus,
18 int addr, int dev_addr,
22 struct pic32_mii_regs *mii_regs = bus->priv;
24 /* Wait for the previous operation to finish */
25 wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
26 false, CONFIG_SYS_HZ, true);
28 /* Put phyaddr and regaddr into MIIMADD */
29 v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
30 writel(v, &mii_regs->madr.raw);
32 /* Initiate a write command */
33 writel(value, &mii_regs->mwtd.raw);
35 /* Wait 30 clock cycles for busy flag to be set */
38 /* Wait for write to complete */
39 wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
40 false, CONFIG_SYS_HZ, true);
45 static int pic32_mdio_read(struct mii_dev *bus, int addr, int devaddr, int reg)
48 struct pic32_mii_regs *mii_regs = bus->priv;
50 /* Wait for the previous operation to finish */
51 wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
52 false, CONFIG_SYS_HZ, true);
54 /* Put phyaddr and regaddr into MIIMADD */
55 v = (addr << MIIMADD_PHYADDR_SHIFT) | (reg & MIIMADD_REGADDR);
56 writel(v, &mii_regs->madr.raw);
58 /* Initiate a read command */
59 writel(MIIMCMD_READ, &mii_regs->mcmd.raw);
61 /* Wait 30 clock cycles for busy flag to be set */
64 /* Wait for read to complete */
65 wait_for_bit(__func__, &mii_regs->mind.raw,
66 MIIMIND_NOTVALID | MIIMIND_BUSY,
67 false, CONFIG_SYS_HZ, false);
69 /* Clear the command register */
70 writel(0, &mii_regs->mcmd.raw);
72 /* Grab the value read from the PHY */
73 v = readl(&mii_regs->mrdd.raw);
77 static int pic32_mdio_reset(struct mii_dev *bus)
79 struct pic32_mii_regs *mii_regs = bus->priv;
81 /* Reset MII (due to new addresses) */
82 writel(MIIMCFG_RSTMGMT, &mii_regs->mcfg.raw);
84 /* Wait for the operation to finish */
85 wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
86 false, CONFIG_SYS_HZ, true);
89 writel(0, &mii_regs->mcfg);
91 /* Wait for the operation to finish */
92 wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
93 false, CONFIG_SYS_HZ, true);
95 /* Set the MII Management Clock (MDC) - no faster than 2.5 MHz */
96 writel(MIIMCFG_CLKSEL_DIV40, &mii_regs->mcfg.raw);
98 /* Wait for the operation to finish */
99 wait_for_bit(__func__, &mii_regs->mind.raw, MIIMIND_BUSY,
100 false, CONFIG_SYS_HZ, true);
104 int pic32_mdio_init(const char *name, ulong ioaddr)
110 printf("Failed to allocate PIC32-MDIO bus\n");
114 bus->read = pic32_mdio_read;
115 bus->write = pic32_mdio_write;
116 bus->reset = pic32_mdio_reset;
117 strncpy(bus->name, name, sizeof(bus->name));
118 bus->priv = (void *)ioaddr;
120 return mdio_register(bus);