1 /* 2 * Freescale MX28EVK board 3 * 4 * (C) Copyright 2011 Freescale Semiconductor, Inc. 5 * 6 * Author: Fabio Estevam <fabio.estevam@freescale.com> 7 * 8 * Based on m28evk.c: 9 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 10 * on behalf of DENX Software Engineering GmbH 11 * 12 * SPDX-License-Identifier: GPL-2.0+ 13 */ 14 15 #include <common.h> 16 #include <asm/gpio.h> 17 #include <asm/io.h> 18 #include <asm/arch/imx-regs.h> 19 #include <asm/arch/iomux-mx28.h> 20 #include <asm/arch/clock.h> 21 #include <asm/arch/sys_proto.h> 22 #include <linux/mii.h> 23 #include <miiphy.h> 24 #include <netdev.h> 25 #include <errno.h> 26 27 DECLARE_GLOBAL_DATA_PTR; 28 29 /* 30 * Functions 31 */ 32 int board_early_init_f(void) 33 { 34 /* IO0 clock at 480MHz */ 35 mxs_set_ioclk(MXC_IOCLK0, 480000); 36 /* IO1 clock at 480MHz */ 37 mxs_set_ioclk(MXC_IOCLK1, 480000); 38 39 /* SSP0 clock at 96MHz */ 40 mxs_set_sspclk(MXC_SSPCLK0, 96000, 0); 41 /* SSP2 clock at 160MHz */ 42 mxs_set_sspclk(MXC_SSPCLK2, 160000, 0); 43 44 #ifdef CONFIG_CMD_USB 45 mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT); 46 mxs_iomux_setup_pad(MX28_PAD_AUART2_RX__GPIO_3_8 | 47 MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL); 48 gpio_direction_output(MX28_PAD_AUART2_RX__GPIO_3_8, 1); 49 #endif 50 51 /* Power on LCD */ 52 gpio_direction_output(MX28_PAD_LCD_RESET__GPIO_3_30, 1); 53 54 /* Set contrast to maximum */ 55 gpio_direction_output(MX28_PAD_PWM2__GPIO_3_18, 1); 56 57 return 0; 58 } 59 60 int dram_init(void) 61 { 62 return mxs_dram_init(); 63 } 64 65 int board_init(void) 66 { 67 /* Adress of boot parameters */ 68 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 69 70 return 0; 71 } 72 73 #ifdef CONFIG_CMD_MMC 74 static int mx28evk_mmc_wp(int id) 75 { 76 if (id != 0) { 77 printf("MXS MMC: Invalid card selected (card id = %d)\n", id); 78 return 1; 79 } 80 81 return gpio_get_value(MX28_PAD_SSP1_SCK__GPIO_2_12); 82 } 83 84 int board_mmc_init(bd_t *bis) 85 { 86 /* Configure WP as input */ 87 gpio_direction_input(MX28_PAD_SSP1_SCK__GPIO_2_12); 88 89 /* Configure MMC0 Power Enable */ 90 gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 0); 91 92 return mxsmmc_initialize(bis, 0, mx28evk_mmc_wp, NULL); 93 } 94 #endif 95 96 #ifdef CONFIG_CMD_NET 97 98 int board_eth_init(bd_t *bis) 99 { 100 struct mxs_clkctrl_regs *clkctrl_regs = 101 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 102 struct eth_device *dev; 103 int ret; 104 105 ret = cpu_eth_init(bis); 106 if (ret) 107 return ret; 108 109 /* MX28EVK uses ENET_CLK PAD to drive FEC clock */ 110 writel(CLKCTRL_ENET_TIME_SEL_RMII_CLK | CLKCTRL_ENET_CLK_OUT_EN, 111 &clkctrl_regs->hw_clkctrl_enet); 112 113 /* Power-on FECs */ 114 gpio_direction_output(MX28_PAD_SSP1_DATA3__GPIO_2_15, 0); 115 116 /* Reset FEC PHYs */ 117 gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0); 118 udelay(200); 119 gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1); 120 121 ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE); 122 if (ret) { 123 puts("FEC MXS: Unable to init FEC0\n"); 124 return ret; 125 } 126 127 ret = fecmxc_initialize_multi(bis, 1, 3, MXS_ENET1_BASE); 128 if (ret) { 129 puts("FEC MXS: Unable to init FEC1\n"); 130 return ret; 131 } 132 133 dev = eth_get_dev_by_name("FEC0"); 134 if (!dev) { 135 puts("FEC MXS: Unable to get FEC0 device entry\n"); 136 return -EINVAL; 137 } 138 139 dev = eth_get_dev_by_name("FEC1"); 140 if (!dev) { 141 puts("FEC MXS: Unable to get FEC1 device entry\n"); 142 return -EINVAL; 143 } 144 145 return ret; 146 } 147 148 #endif 149