3db7816ca810fc4aa81aea60ecc1589c022f0884
[openwrt.git] / package / boot / uboot-oxnas / patches / 200-icplus-phy.patch
1 From e719404ee1241af679a51879eaad291bc27e4817 Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Tue, 2 Dec 2014 14:46:05 +0100
4 Subject: [PATCH] net/phy: add back icplus driver
5
6 IC+ phy driver was removed due to the lack of users some time ago.
7 Add it back, so we can use it.
8 ---
9  drivers/net/phy/Makefile |  1 +
10  drivers/net/phy/icplus.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++
11  drivers/net/phy/phy.c    |  3 ++
12  3 files changed, 84 insertions(+)
13  create mode 100644 drivers/net/phy/icplus.c
14
15 --- a/drivers/net/phy/Makefile
16 +++ b/drivers/net/phy/Makefile
17 @@ -15,6 +15,7 @@ obj-$(CONFIG_PHY_ATHEROS) += atheros.o
18  obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
19  obj-$(CONFIG_PHY_DAVICOM) += davicom.o
20  obj-$(CONFIG_PHY_ET1011C) += et1011c.o
21 +obj-$(CONFIG_PHY_ICPLUS) += icplus.o
22  obj-$(CONFIG_PHY_LXT) += lxt.o
23  obj-$(CONFIG_PHY_MARVELL) += marvell.o
24  obj-$(CONFIG_PHY_MICREL) += micrel.o
25 --- /dev/null
26 +++ b/drivers/net/phy/icplus.c
27 @@ -0,0 +1,80 @@
28 +/*
29 + * ICPlus PHY drivers
30 + *
31 + * SPDX-License-Identifier:    GPL-2.0+
32 + *
33 + * Copyright (c) 2007 Freescale Semiconductor, Inc.
34 + */
35 +#include <phy.h>
36 +
37 +/* IP101A/G - IP1001 */
38 +#define IP10XX_SPEC_CTRL_STATUS         16      /* Spec. Control Register */
39 +#define IP1001_SPEC_CTRL_STATUS_2       20      /* IP1001 Spec. Control Reg 2 */
40 +#define IP1001_PHASE_SEL_MASK           3       /* IP1001 RX/TXPHASE_SEL */
41 +#define IP1001_APS_ON                   11      /* IP1001 APS Mode  bit */
42 +#define IP101A_G_APS_ON                 2       /* IP101A/G APS Mode bit */
43 +#define IP101A_G_IRQ_CONF_STATUS        0x11    /* Conf Info IRQ & Status Reg */
44 +#define IP101A_G_IRQ_PIN_USED           (1<<15) /* INTR pin used */
45 +#define IP101A_G_IRQ_DEFAULT            IP101A_G_IRQ_PIN_USED
46 +
47 +static int ip1001_config(struct phy_device *phydev)
48 +{
49 +       int c;
50 +
51 +       /* Enable Auto Power Saving mode */
52 +       c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2);
53 +       if (c < 0)
54 +               return c;
55 +       c |= IP1001_APS_ON;
56 +       c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c);
57 +       if (c < 0)
58 +               return c;
59 +
60 +       /* INTR pin used: speed/link/duplex will cause an interrupt */
61 +       c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS,
62 +                     IP101A_G_IRQ_DEFAULT);
63 +       if (c < 0)
64 +               return c;
65 +
66 +       if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
67 +               /*
68 +                * Additional delay (2ns) used to adjust RX clock phase
69 +                * at RGMII interface
70 +                */
71 +               c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS);
72 +               if (c < 0)
73 +                       return c;
74 +
75 +               c |= IP1001_PHASE_SEL_MASK;
76 +               c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS,
77 +                             c);
78 +               if (c < 0)
79 +                       return c;
80 +       }
81 +
82 +       return 0;
83 +}
84 +
85 +static int ip1001_startup(struct phy_device *phydev)
86 +{
87 +       genphy_update_link(phydev);
88 +       genphy_parse_link(phydev);
89 +
90 +       return 0;
91 +}
92 +static struct phy_driver IP1001_driver = {
93 +       .name = "ICPlus IP1001",
94 +       .uid = 0x02430d90,
95 +       .mask = 0x0ffffff0,
96 +       .features = PHY_GBIT_FEATURES,
97 +       .config = &ip1001_config,
98 +       .startup = &ip1001_startup,
99 +       .shutdown = &genphy_shutdown,
100 +};
101 +
102 +int phy_icplus_init(void)
103 +{
104 +       phy_register(&IP1001_driver);
105 +
106 +       return 0;
107 +}
108 --- a/drivers/net/phy/phy.c
109 +++ b/drivers/net/phy/phy.c
110 @@ -454,6 +454,9 @@ int phy_init(void)
111  #ifdef CONFIG_PHY_ET1011C
112         phy_et1011c_init();
113  #endif
114 +#ifdef CONFIG_PHY_ICPLUS
115 +       phy_icplus_init();
116 +#endif
117  #ifdef CONFIG_PHY_LXT
118         phy_lxt_init();
119  #endif
120 --- a/include/phy.h
121 +++ b/include/phy.h
122 @@ -225,6 +225,7 @@ int phy_atheros_init(void);
123  int phy_broadcom_init(void);
124  int phy_davicom_init(void);
125  int phy_et1011c_init(void);
126 +int phy_icplus_init(void);
127  int phy_lxt_init(void);
128  int phy_marvell_init(void);
129  int phy_micrel_init(void);