aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mxs/mach-mxs.c
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-07-13 02:15:34 -0400
committerShawn Guo <shawn.guo@linaro.org>2012-08-17 00:35:09 -0400
commit2c7c2c1d01a2559d452c0f0aa5e6f6ca2643e6b1 (patch)
treef2ec81a772baaa2e65986864c30a9bf503fd9e04 /arch/arm/mach-mxs/mach-mxs.c
parentaef35104a9e5b8555cdaeebd4563df9921f6d605 (diff)
ARM: mxs: tx28: reset fec phy for device tree boot
For non-DT boot, function tx28_add_fec0 configures all ENET0 pins into gpio mode for resetting fec phy, and then reconfigures those pins into ENET function after that. For DT boot, all the pin configuration is done by pinctrl subsystem. Ideally, when gpio_request gets called, GPIO subsystem should call pinctrl to configure pins into gpio mode automatically, and have pins freed up from pinctrl subsystem when gpio_free is called. But right now, this cooperation between gpio and pinctrl hasn't been available. As the result, we have to explicitly call pinctrl_get_select and pinctrl_put for device tree boot. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Lothar Waßmann <LW@KARO-electronics.de>
Diffstat (limited to 'arch/arm/mach-mxs/mach-mxs.c')
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c82
1 files changed, 81 insertions, 1 deletions
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index ceb739844780..8378fe5cfaf5 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -12,8 +12,9 @@
12 12
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/clkdev.h> 14#include <linux/clkdev.h>
15#include <linux/delay.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/init.h> 17#include <linux/gpio.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/irqdomain.h> 19#include <linux/irqdomain.h>
19#include <linux/micrel_phy.h> 20#include <linux/micrel_phy.h>
@@ -21,10 +22,12 @@
21#include <linux/of_irq.h> 22#include <linux/of_irq.h>
22#include <linux/of_platform.h> 23#include <linux/of_platform.h>
23#include <linux/phy.h> 24#include <linux/phy.h>
25#include <linux/pinctrl/consumer.h>
24#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
25#include <asm/mach/time.h> 27#include <asm/mach/time.h>
26#include <mach/common.h> 28#include <mach/common.h>
27#include <mach/digctl.h> 29#include <mach/digctl.h>
30#include <mach/mxs.h>
28 31
29static struct fb_videomode mx23evk_video_modes[] = { 32static struct fb_videomode mx23evk_video_modes[] = {
30 { 33 {
@@ -273,6 +276,80 @@ static void __init apx4devkit_init(void)
273 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; 276 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
274} 277}
275 278
279#define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0)
280#define ENET0_MDIO__GPIO_4_1 MXS_GPIO_NR(4, 1)
281#define ENET0_RX_EN__GPIO_4_2 MXS_GPIO_NR(4, 2)
282#define ENET0_RXD0__GPIO_4_3 MXS_GPIO_NR(4, 3)
283#define ENET0_RXD1__GPIO_4_4 MXS_GPIO_NR(4, 4)
284#define ENET0_TX_EN__GPIO_4_6 MXS_GPIO_NR(4, 6)
285#define ENET0_TXD0__GPIO_4_7 MXS_GPIO_NR(4, 7)
286#define ENET0_TXD1__GPIO_4_8 MXS_GPIO_NR(4, 8)
287#define ENET_CLK__GPIO_4_16 MXS_GPIO_NR(4, 16)
288
289#define TX28_FEC_PHY_POWER MXS_GPIO_NR(3, 29)
290#define TX28_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
291#define TX28_FEC_nINT MXS_GPIO_NR(4, 5)
292
293static const struct gpio tx28_gpios[] __initconst = {
294 { ENET0_MDC__GPIO_4_0, GPIOF_OUT_INIT_LOW, "GPIO_4_0" },
295 { ENET0_MDIO__GPIO_4_1, GPIOF_OUT_INIT_LOW, "GPIO_4_1" },
296 { ENET0_RX_EN__GPIO_4_2, GPIOF_OUT_INIT_LOW, "GPIO_4_2" },
297 { ENET0_RXD0__GPIO_4_3, GPIOF_OUT_INIT_LOW, "GPIO_4_3" },
298 { ENET0_RXD1__GPIO_4_4, GPIOF_OUT_INIT_LOW, "GPIO_4_4" },
299 { ENET0_TX_EN__GPIO_4_6, GPIOF_OUT_INIT_LOW, "GPIO_4_6" },
300 { ENET0_TXD0__GPIO_4_7, GPIOF_OUT_INIT_LOW, "GPIO_4_7" },
301 { ENET0_TXD1__GPIO_4_8, GPIOF_OUT_INIT_LOW, "GPIO_4_8" },
302 { ENET_CLK__GPIO_4_16, GPIOF_OUT_INIT_LOW, "GPIO_4_16" },
303 { TX28_FEC_PHY_POWER, GPIOF_OUT_INIT_LOW, "fec-phy-power" },
304 { TX28_FEC_PHY_RESET, GPIOF_OUT_INIT_LOW, "fec-phy-reset" },
305 { TX28_FEC_nINT, GPIOF_DIR_IN, "fec-int" },
306};
307
308static void __init tx28_post_init(void)
309{
310 struct device_node *np;
311 struct platform_device *pdev;
312 struct pinctrl *pctl;
313 int ret;
314
315 enable_clk_enet_out();
316
317 np = of_find_compatible_node(NULL, NULL, "fsl,imx28-fec");
318 pdev = of_find_device_by_node(np);
319 if (!pdev) {
320 pr_err("%s: failed to find fec device\n", __func__);
321 return;
322 }
323
324 pctl = pinctrl_get_select(&pdev->dev, "gpio_mode");
325 if (IS_ERR(pctl)) {
326 pr_err("%s: failed to get pinctrl state\n", __func__);
327 return;
328 }
329
330 ret = gpio_request_array(tx28_gpios, ARRAY_SIZE(tx28_gpios));
331 if (ret) {
332 pr_err("%s: failed to request gpios: %d\n", __func__, ret);
333 return;
334 }
335
336 /* Power up fec phy */
337 gpio_set_value(TX28_FEC_PHY_POWER, 1);
338 msleep(26); /* 25ms according to data sheet */
339
340 /* Mode strap pins */
341 gpio_set_value(ENET0_RX_EN__GPIO_4_2, 1);
342 gpio_set_value(ENET0_RXD0__GPIO_4_3, 1);
343 gpio_set_value(ENET0_RXD1__GPIO_4_4, 1);
344
345 udelay(100); /* minimum assertion time for nRST */
346
347 /* Deasserting FEC PHY RESET */
348 gpio_set_value(TX28_FEC_PHY_RESET, 1);
349
350 pinctrl_put(pctl);
351}
352
276static void __init mxs_machine_init(void) 353static void __init mxs_machine_init(void)
277{ 354{
278 if (of_machine_is_compatible("fsl,imx28-evk")) 355 if (of_machine_is_compatible("fsl,imx28-evk"))
@@ -286,6 +363,9 @@ static void __init mxs_machine_init(void)
286 363
287 of_platform_populate(NULL, of_default_bus_match_table, 364 of_platform_populate(NULL, of_default_bus_match_table,
288 mxs_auxdata_lookup, NULL); 365 mxs_auxdata_lookup, NULL);
366
367 if (of_machine_is_compatible("karo,tx28"))
368 tx28_post_init();
289} 369}
290 370
291static const char *imx23_dt_compat[] __initdata = { 371static const char *imx23_dt_compat[] __initdata = {