aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFugang Duan <b38611@freescale.com>2014-05-13 02:21:30 -0400
committerFugang Duan <b38611@freescale.com>2014-05-15 03:55:06 -0400
commit4bcf608a8a5b74f595faab5b6cb4f4e84e711471 (patch)
tree7ae146b262ff1cd4b8cf62aa69af841919062ec6
parentc7cc578ee6fcbc71b2dd54f36bbb89d3c16e101a (diff)
ENGR00313508-01 ARM: imx6sx: add enet sleep mode support
Add enet sleep mode support for imx6sx arm2 platforms. Signed-off-by: Fugang Duan <B38611@freescale.com>
-rw-r--r--arch/arm/mach-imx/mach-imx6sx.c69
-rw-r--r--include/linux/fec.h3
-rw-r--r--include/linux/mfd/syscon/imx6q-iomuxc-gpr.h3
3 files changed, 74 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index f711895e7019..5d6e50d28b2a 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -10,8 +10,10 @@
10#include <linux/can/platform/flexcan.h> 10#include <linux/can/platform/flexcan.h>
11#include <linux/clk-provider.h> 11#include <linux/clk-provider.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/fec.h>
13#include <linux/gpio.h> 14#include <linux/gpio.h>
14#include <linux/irqchip.h> 15#include <linux/irqchip.h>
16#include <linux/netdevice.h>
15#include <linux/of.h> 17#include <linux/of.h>
16#include <linux/of_address.h> 18#include <linux/of_address.h>
17#include <linux/of_gpio.h> 19#include <linux/of_gpio.h>
@@ -30,6 +32,7 @@
30#include "hardware.h" 32#include "hardware.h"
31 33
32static struct flexcan_platform_data flexcan_pdata[2]; 34static struct flexcan_platform_data flexcan_pdata[2];
35static struct fec_platform_data fec_pdata[2];
33static int flexcan_en_gpio; 36static int flexcan_en_gpio;
34static int flexcan_stby_gpio; 37static int flexcan_stby_gpio;
35static int flexcan0_en; 38static int flexcan0_en;
@@ -109,6 +112,21 @@ static void __init imx6sx_enet_clk_sel(void)
109static int ar8031_phy_fixup(struct phy_device *dev) 112static int ar8031_phy_fixup(struct phy_device *dev)
110{ 113{
111 u16 val; 114 u16 val;
115 unsigned char *addr = NULL;
116
117 /* Fill Wake-on-LAN Internal Address */
118 if (dev->attached_dev) {
119 addr = dev->attached_dev->dev_addr;
120 phy_write(dev, 0xd, 0x3);
121 phy_write(dev, 0xe, 0x804A);
122 phy_write(dev, 0xd, 0xc003);
123 val = (addr[0] << 0x8) | addr[1];
124 phy_write(dev, 0xe, val);
125 val = (addr[2] << 0x8) | addr[3];
126 phy_write(dev, 0xe, val);
127 val = (addr[4] << 0x8) | addr[5];
128 phy_write(dev, 0xe, val);
129 }
112 130
113 /* Set RGMII IO voltage to 1.8V */ 131 /* Set RGMII IO voltage to 1.8V */
114 phy_write(dev, 0x1d, 0x1f); 132 phy_write(dev, 0x1d, 0x1f);
@@ -139,17 +157,68 @@ static void __init imx6sx_enet_phy_init(void)
139 ar8031_phy_fixup); 157 ar8031_phy_fixup);
140} 158}
141 159
160static void imx6sx_fec1_stop_enable(int enabled)
161{
162 struct regmap *gpr;
163
164 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sx-iomuxc-gpr");
165 if (!IS_ERR(gpr)) {
166 if (enabled)
167 regmap_update_bits(gpr, IOMUXC_GPR4,
168 IMX6SX_GPR4_FEC_ENET1_STOP_REQ,
169 IMX6SX_GPR4_FEC_ENET1_STOP_REQ);
170 else
171 regmap_update_bits(gpr, IOMUXC_GPR4,
172 IMX6SX_GPR4_FEC_ENET1_STOP_REQ, 0);
173
174 } else
175 pr_err("failed to find fsl,imx6sx-iomux-gpr regmap\n");
176}
177
178static void imx6sx_fec2_stop_enable(int enabled)
179{
180 struct regmap *gpr;
181
182 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sx-iomuxc-gpr");
183 if (!IS_ERR(gpr)) {
184 if (enabled)
185 regmap_update_bits(gpr, IOMUXC_GPR4,
186 IMX6SX_GPR4_FEC_ENET2_STOP_REQ,
187 IMX6SX_GPR4_FEC_ENET2_STOP_REQ);
188 else
189 regmap_update_bits(gpr, IOMUXC_GPR4,
190 IMX6SX_GPR4_FEC_ENET2_STOP_REQ, 0);
191
192 } else
193 pr_err("failed to find fsl,imx6sx-iomux-gpr regmap\n");
194}
195
196static void __init imx6sx_enet_plt_init(void)
197{
198 struct device_node *np;
199
200 np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000");
201 if (np && of_get_property(np, "fsl,magic-packet", NULL))
202 fec_pdata[0].sleep_mode_enable = imx6sx_fec1_stop_enable;
203 np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@021b4000");
204 if (np && of_get_property(np, "fsl,magic-packet", NULL))
205 fec_pdata[1].sleep_mode_enable = imx6sx_fec2_stop_enable;
206}
207
142static inline void imx6sx_enet_init(void) 208static inline void imx6sx_enet_init(void)
143{ 209{
144 imx6_enet_mac_init("fsl,imx6sx-fec"); 210 imx6_enet_mac_init("fsl,imx6sx-fec");
145 imx6sx_enet_phy_init(); 211 imx6sx_enet_phy_init();
146 imx6sx_enet_clk_sel(); 212 imx6sx_enet_clk_sel();
213 imx6sx_enet_plt_init();
147} 214}
148 215
149/* Add auxdata to pass platform data */ 216/* Add auxdata to pass platform data */
150static const struct of_dev_auxdata imx6sx_auxdata_lookup[] __initconst = { 217static const struct of_dev_auxdata imx6sx_auxdata_lookup[] __initconst = {
151 OF_DEV_AUXDATA("fsl,imx6q-flexcan", 0x02090000, NULL, &flexcan_pdata[0]), 218 OF_DEV_AUXDATA("fsl,imx6q-flexcan", 0x02090000, NULL, &flexcan_pdata[0]),
152 OF_DEV_AUXDATA("fsl,imx6q-flexcan", 0x02094000, NULL, &flexcan_pdata[1]), 219 OF_DEV_AUXDATA("fsl,imx6q-flexcan", 0x02094000, NULL, &flexcan_pdata[1]),
220 OF_DEV_AUXDATA("fsl,imx6sx-fec", 0x02188000, NULL, &fec_pdata[0]),
221 OF_DEV_AUXDATA("fsl,imx6sx-fec", 0x021b4000, NULL, &fec_pdata[1]),
153 { /* sentinel */ } 222 { /* sentinel */ }
154}; 223};
155 224
diff --git a/include/linux/fec.h b/include/linux/fec.h
index bcff455d1d53..ef3c72ca6a66 100644
--- a/include/linux/fec.h
+++ b/include/linux/fec.h
@@ -3,7 +3,7 @@
3 * Copyright (c) 2009 Orex Computed Radiography 3 * Copyright (c) 2009 Orex Computed Radiography
4 * Baruch Siach <baruch@tkos.co.il> 4 * Baruch Siach <baruch@tkos.co.il>
5 * 5 *
6 * Copyright (C) 2010 Freescale Semiconductor, Inc. 6 * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
7 * 7 *
8 * Header file for the FEC platform data 8 * Header file for the FEC platform data
9 * 9 *
@@ -19,6 +19,7 @@
19struct fec_platform_data { 19struct fec_platform_data {
20 phy_interface_t phy; 20 phy_interface_t phy;
21 unsigned char mac[ETH_ALEN]; 21 unsigned char mac[ETH_ALEN];
22 void (*sleep_mode_enable)(int enabled);
22}; 23};
23 24
24#endif 25#endif
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
index c570e71471c4..dc7f6633768b 100644
--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -399,6 +399,9 @@
399#define IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK (0x3 << 17) 399#define IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK (0x3 << 17)
400#define IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_EXT (0x3 << 13) 400#define IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_EXT (0x3 << 13)
401 401
402#define IMX6SX_GPR4_FEC_ENET1_STOP_REQ (0x1 << 3)
403#define IMX6SX_GPR4_FEC_ENET2_STOP_REQ (0x1 << 4)
404
402#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_MASK (0x1 << 3) 405#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_MASK (0x1 << 3)
403#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF1 (0x0 << 3) 406#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF1 (0x0 << 3)
404#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF2 (0x1 << 3) 407#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF2 (0x1 << 3)