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