]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/net/pic32_mdio.c
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
);