diff options
-rw-r--r-- | arch/arm/mach-mxs/mach-mx28evk.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c new file mode 100644 index 0000000..d162e95 --- /dev/null +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -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 |