]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_mdio.c
1 /*******************************************************************************
2   STMMAC Ethernet Driver -- MDIO bus implementation
3   Provides Bus interface for MII registers
4
5   Copyright (C) 2007-2009  STMicroelectronics Ltd
6
7   This program is free software; you can redistribute it and/or modify it
8   under the terms and conditions of the GNU General Public License,
9   version 2, as published by the Free Software Foundation.
10
11   This program is distributed in the hope it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14   more details.
15
16   The full GNU General Public License is included in this distribution in
17   the file called "COPYING".
18
19   Author: Carl Shaw <carl.shaw@st.com>
20   Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21 *******************************************************************************/
22
23 #include <linux/io.h>
24 #include <linux/iopoll.h>
25 #include <linux/mii.h>
26 #include <linux/of.h>
27 #include <linux/of_gpio.h>
28 #include <linux/of_mdio.h>
29 #include <linux/phy.h>
30 #include <linux/slab.h>
31
32 #include "stmmac.h"
33
34 #define MII_BUSY 0x00000001
35 #define MII_WRITE 0x00000002
36
37 /* GMAC4 defines */
38 #define MII_GMAC4_GOC_SHIFT             2
39 #define MII_GMAC4_WRITE                 (1 << MII_GMAC4_GOC_SHIFT)
40 #define MII_GMAC4_READ                  (3 << MII_GMAC4_GOC_SHIFT)
41
42 /**
43  * stmmac_mdio_read
44  * @bus: points to the mii_bus structure
45  * @phyaddr: MII addr
46  * @phyreg: MII reg
47  * Description: it reads data from the MII register from within the phy device.
48  * For the 7111 GMAC, we must set the bit 0 in the MII address register while
49  * accessing the PHY registers.
50  * Fortunately, it seems this has no drawback for the 7109 MAC.
51  */
52 static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
53 {
54         struct net_device *ndev = bus->priv;
55         struct stmmac_priv *priv = netdev_priv(ndev);
56         unsigned int mii_address = priv->hw->mii.addr;
57         unsigned int mii_data = priv->hw->mii.data;
58         u32 v;
59         int data;
60         u32 value = MII_BUSY;
61
62         value |= (phyaddr << priv->hw->mii.addr_shift)
63                 & priv->hw->mii.addr_mask;
64         value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
65         value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
66                 & priv->hw->mii.clk_csr_mask;
67         if (priv->plat->has_gmac4)
68                 value |= MII_GMAC4_READ;
69
70         if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
71                                100, 10000))
72                 return -EBUSY;
73
74         writel(value, priv->ioaddr + mii_address);
75
76         if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
77                                100, 10000))
78                 return -EBUSY;
79
80         /* Read the data from the MII data register */
81         data = (int)readl(priv->ioaddr + mii_data);
82
83         return data;
84 }
85
86 /**
87  * stmmac_mdio_write
88  * @bus: points to the mii_bus structure
89  * @phyaddr: MII addr
90  * @phyreg: MII reg
91  * @phydata: phy data
92  * Description: it writes the data into the MII register from within the device.
93  */
94 static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
95                              u16 phydata)
96 {
97         struct net_device *ndev = bus->priv;
98         struct stmmac_priv *priv = netdev_priv(ndev);
99         unsigned int mii_address = priv->hw->mii.addr;
100         unsigned int mii_data = priv->hw->mii.data;
101         u32 v;
102         u32 value = MII_BUSY;
103
104         value |= (phyaddr << priv->hw->mii.addr_shift)
105                 & priv->hw->mii.addr_mask;
106         value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
107
108         value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
109                 & priv->hw->mii.clk_csr_mask;
110         if (priv->plat->has_gmac4)
111                 value |= MII_GMAC4_WRITE;
112         else
113                 value |= MII_WRITE;
114
115         /* Wait until any existing MII operation is complete */
116         if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
117                                100, 10000))
118                 return -EBUSY;
119
120         /* Set the MII address register to write */
121         writel(phydata, priv->ioaddr + mii_data);
122         writel(value, priv->ioaddr + mii_address);
123
124         /* Wait until any existing MII operation is complete */
125         return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
126                                   100, 10000);
127 }
128
129 /**
130  * stmmac_mdio_reset
131  * @bus: points to the mii_bus structure
132  * Description: reset the MII bus
133  */
134 int stmmac_mdio_reset(struct mii_bus *bus)
135 {
136 #if defined(CONFIG_STMMAC_PLATFORM)
137         struct net_device *ndev = bus->priv;
138         struct stmmac_priv *priv = netdev_priv(ndev);
139         unsigned int mii_address = priv->hw->mii.addr;
140         struct stmmac_mdio_bus_data *data = priv->plat->mdio_bus_data;
141
142 #ifdef CONFIG_OF
143         if (priv->device->of_node) {
144                 if (data->reset_gpio < 0) {
145                         struct device_node *np = priv->device->of_node;
146
147                         if (!np)
148                                 return 0;
149
150                         data->reset_gpio = of_get_named_gpio(np,
151                                                 "snps,reset-gpio", 0);
152                         if (data->reset_gpio < 0)
153                                 return 0;
154
155                         data->active_low = of_property_read_bool(np,
156                                                 "snps,reset-active-low");
157                         of_property_read_u32_array(np,
158                                 "snps,reset-delays-us", data->delays, 3);
159
160                         if (gpio_request(data->reset_gpio, "mdio-reset"))
161                                 return 0;
162                 }
163
164                 gpio_direction_output(data->reset_gpio,
165                                       data->active_low ? 1 : 0);
166                 if (data->delays[0])
167                         msleep(DIV_ROUND_UP(data->delays[0], 1000));
168
169                 gpio_set_value(data->reset_gpio, data->active_low ? 0 : 1);
170                 if (data->delays[1])
171                         msleep(DIV_ROUND_UP(data->delays[1], 1000));
172
173                 gpio_set_value(data->reset_gpio, data->active_low ? 1 : 0);
174                 if (data->delays[2])
175                         msleep(DIV_ROUND_UP(data->delays[2], 1000));
176         }
177 #endif
178
179         if (data->phy_reset) {
180                 netdev_dbg(ndev, "stmmac_mdio_reset: calling phy_reset\n");
181                 data->phy_reset(priv->plat->bsp_priv);
182         }
183
184         /* This is a workaround for problems with the STE101P PHY.
185          * It doesn't complete its reset until at least one clock cycle
186          * on MDC, so perform a dummy mdio read. To be updated for GMAC4
187          * if needed.
188          */
189         if (!priv->plat->has_gmac4)
190                 writel(0, priv->ioaddr + mii_address);
191 #endif
192         return 0;
193 }
194
195 /**
196  * stmmac_mdio_register
197  * @ndev: net device structure
198  * Description: it registers the MII bus
199  */
200 int stmmac_mdio_register(struct net_device *ndev)
201 {
202         int err = 0;
203         struct mii_bus *new_bus;
204         struct stmmac_priv *priv = netdev_priv(ndev);
205         struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
206         struct device_node *mdio_node = priv->plat->mdio_node;
207         struct device *dev = ndev->dev.parent;
208         int addr, found;
209
210         if (!mdio_bus_data)
211                 return 0;
212
213         new_bus = mdiobus_alloc();
214         if (!new_bus)
215                 return -ENOMEM;
216
217         if (mdio_bus_data->irqs)
218                 memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
219
220 #ifdef CONFIG_OF
221         if (priv->device->of_node)
222                 mdio_bus_data->reset_gpio = -1;
223 #endif
224
225         new_bus->name = "stmmac";
226         new_bus->read = &stmmac_mdio_read;
227         new_bus->write = &stmmac_mdio_write;
228
229         new_bus->reset = &stmmac_mdio_reset;
230         snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
231                  new_bus->name, priv->plat->bus_id);
232         new_bus->priv = ndev;
233         new_bus->phy_mask = mdio_bus_data->phy_mask;
234         new_bus->parent = priv->device;
235
236         if (mdio_node)
237                 err = of_mdiobus_register(new_bus, mdio_node);
238         else
239                 err = mdiobus_register(new_bus);
240         if (err != 0) {
241                 dev_err(dev, "Cannot register the MDIO bus\n");
242                 goto bus_register_fail;
243         }
244
245         if (priv->plat->phy_node || mdio_node)
246                 goto bus_register_done;
247
248         found = 0;
249         for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
250                 struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
251                 int act = 0;
252                 char irq_num[4];
253                 char *irq_str;
254
255                 if (!phydev)
256                         continue;
257
258                 /*
259                  * If an IRQ was provided to be assigned after
260                  * the bus probe, do it here.
261                  */
262                 if (!mdio_bus_data->irqs &&
263                     (mdio_bus_data->probed_phy_irq > 0)) {
264                         new_bus->irq[addr] = mdio_bus_data->probed_phy_irq;
265                         phydev->irq = mdio_bus_data->probed_phy_irq;
266                 }
267
268                 /*
269                  * If we're going to bind the MAC to this PHY bus,
270                  * and no PHY number was provided to the MAC,
271                  * use the one probed here.
272                  */
273                 if (priv->plat->phy_addr == -1)
274                         priv->plat->phy_addr = addr;
275
276                 act = (priv->plat->phy_addr == addr);
277                 switch (phydev->irq) {
278                 case PHY_POLL:
279                         irq_str = "POLL";
280                         break;
281                 case PHY_IGNORE_INTERRUPT:
282                         irq_str = "IGNORE";
283                         break;
284                 default:
285                         sprintf(irq_num, "%d", phydev->irq);
286                         irq_str = irq_num;
287                         break;
288                 }
289                 phy_attached_info(phydev);
290                 found = 1;
291         }
292
293         if (!found && !mdio_node) {
294                 dev_warn(dev, "No PHY found\n");
295                 mdiobus_unregister(new_bus);
296                 mdiobus_free(new_bus);
297                 return -ENODEV;
298         }
299
300 bus_register_done:
301         priv->mii = new_bus;
302
303         return 0;
304
305 bus_register_fail:
306         mdiobus_free(new_bus);
307         return err;
308 }
309
310 /**
311  * stmmac_mdio_unregister
312  * @ndev: net device structure
313  * Description: it unregisters the MII bus
314  */
315 int stmmac_mdio_unregister(struct net_device *ndev)
316 {
317         struct stmmac_priv *priv = netdev_priv(ndev);
318
319         if (!priv->mii)
320                 return 0;
321
322         mdiobus_unregister(priv->mii);
323         priv->mii->priv = NULL;
324         mdiobus_free(priv->mii);
325         priv->mii = NULL;
326
327         return 0;
328 }