1
2
3
4
5
6
7
8#include <common.h>
9#include <miiphy.h>
10#include <phy.h>
11#include <asm/io.h>
12#include <asm/fsl_tgec.h>
13#include <fm_eth.h>
14
15
16
17
18
19
20static int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
21 int regnum, u16 value)
22{
23 u32 mdio_ctl;
24 u32 stat_val;
25 struct tgec_mdio_controller *regs = bus->priv;
26
27 if (dev_addr == MDIO_DEVAD_NONE)
28 return 0;
29
30
31 stat_val = MDIO_STAT_CLKDIV(100);
32 out_be32(®s->mdio_stat, stat_val);
33 while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY)
34 ;
35
36
37 mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
38 out_be32(®s->mdio_ctl, mdio_ctl);
39
40
41 out_be32(®s->mdio_addr, regnum & 0xffff);
42
43
44 while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY)
45 ;
46
47
48 out_be32(®s->mdio_data, MDIO_DATA(value));
49
50
51 while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY)
52 ;
53
54 return 0;
55}
56
57
58
59
60
61
62static int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
63 int regnum)
64{
65 u32 mdio_ctl;
66 u32 stat_val;
67 struct tgec_mdio_controller *regs = bus->priv;
68
69 if (dev_addr == MDIO_DEVAD_NONE)
70 return 0xffff;
71
72 stat_val = MDIO_STAT_CLKDIV(100);
73 out_be32(®s->mdio_stat, stat_val);
74
75 while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY)
76 ;
77
78
79 mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
80 out_be32(®s->mdio_ctl, mdio_ctl);
81
82
83 out_be32(®s->mdio_addr, regnum & 0xffff);
84
85
86 while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY)
87 ;
88
89
90 mdio_ctl |= MDIO_CTL_READ;
91 out_be32(®s->mdio_ctl, mdio_ctl);
92
93
94 while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY)
95 ;
96
97
98 if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER)
99 return 0xffff;
100
101 return in_be32(®s->mdio_data) & 0xffff;
102}
103
104static int tgec_mdio_reset(struct mii_dev *bus)
105{
106 return 0;
107}
108
109int fm_tgec_mdio_init(bd_t *bis, struct tgec_mdio_info *info)
110{
111 struct mii_dev *bus = mdio_alloc();
112
113 if (!bus) {
114 printf("Failed to allocate FM TGEC MDIO bus\n");
115 return -1;
116 }
117
118 bus->read = tgec_mdio_read;
119 bus->write = tgec_mdio_write;
120 bus->reset = tgec_mdio_reset;
121 sprintf(bus->name, info->name);
122
123 bus->priv = info->regs;
124
125 return mdio_register(bus);
126}
127