/* * 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 #include #include #include #include #include #include #include #include #include #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), /* fec1 */ MX28_PAD_ENET0_CRS__ENET1_RX_EN | (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), MX28_PAD_ENET0_RXD2__ENET1_RXD0 | (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), MX28_PAD_ENET0_RXD3__ENET1_RXD1 | (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), MX28_PAD_ENET0_COL__ENET1_TX_EN | (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), MX28_PAD_ENET0_TXD2__ENET1_TXD0 | (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), MX28_PAD_ENET0_TXD3__ENET1_TXD1 | (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 struct fec_platform_data mx28_fec_pdata[] = { { /* fec0 */ .phy = PHY_INTERFACE_MODE_RMII, }, { /* fec1 */ .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[0]); mx28_add_fec(1, &mx28_fec_pdata[1]); } 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