]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/phy/icplus.c
Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
[karo-tx-uboot.git] / drivers / net / phy / icplus.c
1 /*
2  * ICPlus PHY drivers
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307 USA
18  *
19  * Copyright (c) 2007 Freescale Semiconductor, Inc.
20  *
21  */
22 #include <phy.h>
23
24 /* IP101A/G - IP1001 */
25 #define IP10XX_SPEC_CTRL_STATUS         16      /* Spec. Control Register */
26 #define IP1001_SPEC_CTRL_STATUS_2       20      /* IP1001 Spec. Control Reg 2 */
27 #define IP1001_PHASE_SEL_MASK           3       /* IP1001 RX/TXPHASE_SEL */
28 #define IP1001_APS_ON                   11      /* IP1001 APS Mode  bit */
29 #define IP101A_G_APS_ON                 2       /* IP101A/G APS Mode bit */
30 #define IP101A_G_IRQ_CONF_STATUS        0x11    /* Conf Info IRQ & Status Reg */
31 #define IP101A_G_IRQ_PIN_USED           (1<<15) /* INTR pin used */
32 #define IP101A_G_IRQ_DEFAULT            IP101A_G_IRQ_PIN_USED
33
34 static int ip1001_config(struct phy_device *phydev)
35 {
36         int c;
37
38         /* Enable Auto Power Saving mode */
39         c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2);
40         if (c < 0)
41                 return c;
42         c |= IP1001_APS_ON;
43         c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c);
44         if (c < 0)
45                 return c;
46
47         /* INTR pin used: speed/link/duplex will cause an interrupt */
48         c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS,
49                       IP101A_G_IRQ_DEFAULT);
50         if (c < 0)
51                 return c;
52
53         if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
54                 /*
55                  * Additional delay (2ns) used to adjust RX clock phase
56                  * at RGMII interface
57                  */
58                 c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS);
59                 if (c < 0)
60                         return c;
61
62                 c |= IP1001_PHASE_SEL_MASK;
63                 c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS,
64                               c);
65                 if (c < 0)
66                         return c;
67         }
68
69         return 0;
70 }
71
72 static int ip1001_startup(struct phy_device *phydev)
73 {
74         genphy_update_link(phydev);
75         genphy_parse_link(phydev);
76
77         return 0;
78 }
79 static struct phy_driver IP1001_driver = {
80         .name = "ICPlus IP1001",
81         .uid = 0x02430d90,
82         .mask = 0x0ffffff0,
83         .features = PHY_GBIT_FEATURES,
84         .config = &ip1001_config,
85         .startup = &ip1001_startup,
86         .shutdown = &genphy_shutdown,
87 };
88
89 int phy_icplus_init(void)
90 {
91         phy_register(&IP1001_driver);
92
93         return 0;
94 }