1/* 2 * (C) Copyright 2007 3 * Sascha Hauer, Pengutronix 4 * 5 * (C) Copyright 2009 Freescale Semiconductor, Inc. 6 * 7 * See file CREDITS for list of people who contributed to this 8 * project. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 */ 25 26#include <common.h> 27#include <asm/arch/imx-regs.h> 28#include <asm/arch/clock.h> 29#include <asm/errno.h> 30#include <asm/io.h> 31 32#ifdef CONFIG_FSL_ESDHC 33#include <fsl_esdhc.h> 34#endif 35 36#if !(defined(CONFIG_MX51) || defined(CONFIG_MX53)) 37#error "CPU_TYPE not defined" 38#endif 39 40u32 get_cpu_rev(void) 41{ 42#ifdef CONFIG_MX51 43 int system_rev = 0x51000; 44#else 45 int system_rev = 0x53000; 46#endif 47 int reg = __raw_readl(ROM_SI_REV); 48 49#if defined(CONFIG_MX51) 50 switch (reg) { 51 case 0x02: 52 system_rev |= CHIP_REV_1_1; 53 break; 54 case 0x10: 55 if ((__raw_readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) 56 system_rev |= CHIP_REV_2_5; 57 else 58 system_rev |= CHIP_REV_2_0; 59 break; 60 case 0x20: 61 system_rev |= CHIP_REV_3_0; 62 break; 63 default: 64 system_rev |= CHIP_REV_1_0; 65 break; 66 } 67#else 68 if (reg < 0x20) 69 system_rev |= CHIP_REV_1_0; 70 else 71 system_rev |= reg; 72#endif 73 return system_rev; 74} 75 76static char *get_reset_cause(void) 77{ 78 u32 cause; 79 struct src *src_regs = (struct src *)SRC_BASE_ADDR; 80 81 cause = readl(&src_regs->srsr); 82 writel(cause, &src_regs->srsr); 83 84 switch (cause) { 85 case 0x00001: 86 return "POR"; 87 case 0x00004: 88 return "CSU"; 89 case 0x00008: 90 return "IPP USER"; 91 case 0x00010: 92 return "WDOG"; 93 case 0x00020: 94 return "JTAG HIGH-Z"; 95 case 0x00040: 96 return "JTAG SW"; 97 case 0x10000: 98 return "WARM BOOT"; 99 default: 100 return "unknown reset"; 101 } 102} 103 104#if defined(CONFIG_DISPLAY_CPUINFO) 105int print_cpuinfo(void) 106{ 107 u32 cpurev; 108 109 cpurev = get_cpu_rev(); 110 printf("CPU: Freescale i.MX%x family rev%d.%d at %d MHz\n", 111 (cpurev & 0xFF000) >> 12, 112 (cpurev & 0x000F0) >> 4, 113 (cpurev & 0x0000F) >> 0, 114 mxc_get_clock(MXC_ARM_CLK) / 1000000); 115 printf("Reset cause: %s\n", get_reset_cause()); 116 return 0; 117} 118#endif 119 120/* 121 * Initializes on-chip ethernet controllers. 122 * to override, implement board_eth_init() 123 */ 124#if defined(CONFIG_FEC_MXC) 125extern int fecmxc_initialize(bd_t *bis); 126#endif 127 128int cpu_eth_init(bd_t *bis) 129{ 130 int rc = -ENODEV; 131 132#if defined(CONFIG_FEC_MXC) 133 rc = fecmxc_initialize(bis); 134#endif 135 136 return rc; 137} 138 139#if defined(CONFIG_FEC_MXC) 140void imx_get_mac_from_fuse(unsigned char *mac) 141{ 142 int i; 143 struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; 144 struct fuse_bank *bank = &iim->bank[1]; 145 struct fuse_bank1_regs *fuse = 146 (struct fuse_bank1_regs *)bank->fuse_regs; 147 148 for (i = 0; i < 6; i++) 149 mac[i] = readl(&fuse->mac_addr[i]) & 0xff; 150} 151#endif 152 153/* 154 * Initializes on-chip MMC controllers. 155 * to override, implement board_mmc_init() 156 */ 157int cpu_mmc_init(bd_t *bis) 158{ 159#ifdef CONFIG_FSL_ESDHC 160 return fsl_esdhc_mmc_init(bis); 161#else 162 return 0; 163#endif 164} 165 166void set_chipselect_size(int const cs_size) 167{ 168 unsigned int reg; 169 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; 170 reg = readl(&iomuxc_regs->gpr1); 171 172 switch (cs_size) { 173 case CS0_128: 174 reg &= ~0x7; /* CS0=128MB, CS1=0, CS2=0, CS3=0 */ 175 reg |= 0x5; 176 break; 177 case CS0_64M_CS1_64M: 178 reg &= ~0x3F; /* CS0=64MB, CS1=64MB, CS2=0, CS3=0 */ 179 reg |= 0x1B; 180 break; 181 case CS0_64M_CS1_32M_CS2_32M: 182 reg &= ~0x1FF; /* CS0=64MB, CS1=32MB, CS2=32MB, CS3=0 */ 183 reg |= 0x4B; 184 break; 185 case CS0_32M_CS1_32M_CS2_32M_CS3_32M: 186 reg &= ~0xFFF; /* CS0=32MB, CS1=32MB, CS2=32MB, CS3=32MB */ 187 reg |= 0x249; 188 break; 189 default: 190 printf("Unknown chip select size: %d\n", cs_size); 191 break; 192 } 193 194 writel(reg, &iomuxc_regs->gpr1); 195} 196 197void reset_cpu(ulong addr) 198{ 199 __raw_writew(4, WDOG1_BASE_ADDR); 200} 201