ARM: mxs: Add initial mx28evk support
authorShawn Guo <shawn.guo@freescale.com>
Sat, 18 Dec 2010 13:39:35 +0000 (21:39 +0800)
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Mon, 20 Dec 2010 16:30:43 +0000 (17:30 +0100)
Add initial mx28evk support with duart and fec0.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
arch/arm/mach-mxs/mach-mx28evk.c [new file with mode: 0644]

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644 (file)
index 0000000..d162e95
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+#include "gpio.h"
+
+#define MX28EVK_FEC_PHY_POWER  MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET  MXS_GPIO_NR(4, 13)
+
+static const iomux_cfg_t mx28evk_pads[] __initconst = {
+       /* duart */
+       MX28_PAD_PWM0__DUART_RX |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       MX28_PAD_PWM1__DUART_TX |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+       /* fec0 */
+       MX28_PAD_ENET0_MDC__ENET0_MDC |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET0_MDIO__ENET0_MDIO |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET0_RX_EN__ENET0_RX_EN |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET0_RXD0__ENET0_RXD0 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET0_RXD1__ENET0_RXD1 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET0_TX_EN__ENET0_TX_EN |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET0_TXD0__ENET0_TXD0 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET0_TXD1__ENET0_TXD1 |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       MX28_PAD_ENET_CLK__CLKCTRL_ENET |
+               (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+       /* phy power line */
+       MX28_PAD_SSP1_DATA3__GPIO_2_15 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+       /* phy reset line */
+       MX28_PAD_ENET0_RX_CLK__GPIO_4_13 |
+               (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+};
+
+/* fec */
+static void __init mx28evk_fec_reset(void)
+{
+       int ret;
+       struct clk *clk;
+
+       /* Enable fec phy clock */
+       clk = clk_get_sys("pll2", NULL);
+       if (!IS_ERR(clk))
+               clk_enable(clk);
+
+       /* Power up fec phy */
+       ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+       if (ret) {
+               pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
+               return;
+       }
+
+       ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+       if (ret) {
+               pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
+               return;
+       }
+
+       /* Reset fec phy */
+       ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+       if (ret) {
+               pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
+               return;
+       }
+
+       gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+       if (ret) {
+               pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
+               return;
+       }
+
+       mdelay(1);
+       gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+       .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+       mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+       mx28_add_duart();
+
+       mx28evk_fec_reset();
+       mx28_add_fec(0, &mx28_fec_pdata);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+       mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+       .init   = mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+       /* Maintainer: Freescale Semiconductor, Inc. */
+       .map_io         = mx28_map_io,
+       .init_irq       = mx28_init_irq,
+       .init_machine   = mx28evk_init,
+       .timer          = &mx28evk_timer,
+MACHINE_END