3db7816ca810fc4aa81aea60ecc1589c022f0884
[openwrt/staging/mkresin.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);