1 /* 2 * Copyright (C) 2007 Freescale Semiconductor, Inc. 3 * Dave Liu <daveliu@freescale.com> 4 * 5 * CREDITS: Kim Phillips contribute to LIBFDT code 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 */ 12 13 #include <common.h> 14 #include <i2c.h> 15 #include <asm/io.h> 16 #include <asm/fsl_serdes.h> 17 #include <spd_sdram.h> 18 #include <tsec.h> 19 #if defined(CONFIG_OF_LIBFDT) 20 #include <libfdt.h> 21 #endif 22 #if defined(CONFIG_PQ_MDS_PIB) 23 #include "../common/pq-mds-pib.h" 24 #endif 25 26 int board_early_init_f(void) 27 { 28 u8 *bcsr = (u8 *)CONFIG_SYS_BCSR; 29 30 /* Enable flash write */ 31 bcsr[0x9] &= ~0x04; 32 /* Clear all of the interrupt of BCSR */ 33 bcsr[0xe] = 0xff; 34 35 #ifdef CONFIG_FSL_SERDES 36 immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 37 u32 spridr = in_be32(&immr->sysconf.spridr); 38 39 /* we check only part num, and don't look for CPU revisions */ 40 switch (PARTID_NO_E(spridr)) { 41 case SPR_8377: 42 fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA, 43 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 44 fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX, 45 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 46 break; 47 case SPR_8378: 48 fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SGMII, 49 FSL_SERDES_CLK_125, FSL_SERDES_VDD_1V); 50 fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX, 51 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 52 break; 53 case SPR_8379: 54 fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA, 55 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 56 fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_SATA, 57 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 58 break; 59 default: 60 printf("serdes not configured: unknown CPU part number: " 61 "%04x\n", spridr >> 16); 62 break; 63 } 64 #endif /* CONFIG_FSL_SERDES */ 65 return 0; 66 } 67 68 #if defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2) 69 int board_eth_init(bd_t *bd) 70 { 71 struct tsec_info_struct tsec_info[2]; 72 struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; 73 u32 rcwh = in_be32(&im->reset.rcwh); 74 u32 tsec_mode; 75 int num = 0; 76 77 /* New line after Net: */ 78 printf("\n"); 79 80 #ifdef CONFIG_TSEC1 81 SET_STD_TSEC_INFO(tsec_info[num], 1); 82 83 printf(CONFIG_TSEC1_NAME ": "); 84 85 tsec_mode = rcwh & HRCWH_TSEC1M_MASK; 86 if (tsec_mode == HRCWH_TSEC1M_IN_RGMII) { 87 printf("RGMII\n"); 88 /* this is default, no need to fixup */ 89 } else if (tsec_mode == HRCWH_TSEC1M_IN_SGMII) { 90 printf("SGMII\n"); 91 tsec_info[num].phyaddr = TSEC1_PHY_ADDR_SGMII; 92 tsec_info[num].flags = TSEC_GIGABIT; 93 } else { 94 printf("unsupported PHY type\n"); 95 } 96 num++; 97 #endif 98 #ifdef CONFIG_TSEC2 99 SET_STD_TSEC_INFO(tsec_info[num], 2); 100 101 printf(CONFIG_TSEC2_NAME ": "); 102 103 tsec_mode = rcwh & HRCWH_TSEC2M_MASK; 104 if (tsec_mode == HRCWH_TSEC2M_IN_RGMII) { 105 printf("RGMII\n"); 106 /* this is default, no need to fixup */ 107 } else if (tsec_mode == HRCWH_TSEC2M_IN_SGMII) { 108 printf("SGMII\n"); 109 tsec_info[num].phyaddr = TSEC2_PHY_ADDR_SGMII; 110 tsec_info[num].flags = TSEC_GIGABIT; 111 } else { 112 printf("unsupported PHY type\n"); 113 } 114 num++; 115 #endif 116 return tsec_eth_init(bd, tsec_info, num); 117 } 118 119 static void __ft_tsec_fixup(void *blob, bd_t *bd, const char *alias, 120 int phy_addr) 121 { 122 const char *phy_type = "sgmii"; 123 const u32 *ph; 124 int off; 125 int err; 126 127 off = fdt_path_offset(blob, alias); 128 if (off < 0) { 129 printf("WARNING: could not find %s alias: %s.\n", alias, 130 fdt_strerror(off)); 131 return; 132 } 133 134 err = fdt_setprop(blob, off, "phy-connection-type", phy_type, 135 strlen(phy_type) + 1); 136 if (err) { 137 printf("WARNING: could not set phy-connection-type for %s: " 138 "%s.\n", alias, fdt_strerror(err)); 139 return; 140 } 141 142 ph = (u32 *)fdt_getprop(blob, off, "phy-handle", 0); 143 if (!ph) { 144 printf("WARNING: could not get phy-handle for %s.\n", 145 alias); 146 return; 147 } 148 149 off = fdt_node_offset_by_phandle(blob, *ph); 150 if (off < 0) { 151 printf("WARNING: could not get phy node for %s: %s\n", alias, 152 fdt_strerror(off)); 153 return; 154 } 155 156 phy_addr = cpu_to_fdt32(phy_addr); 157 err = fdt_setprop(blob, off, "reg", &phy_addr, sizeof(phy_addr)); 158 if (err < 0) { 159 printf("WARNING: could not set phy node's reg for %s: " 160 "%s.\n", alias, fdt_strerror(err)); 161 return; 162 } 163 } 164 165 static void ft_tsec_fixup(void *blob, bd_t *bd) 166 { 167 struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; 168 u32 rcwh = in_be32(&im->reset.rcwh); 169 u32 tsec_mode; 170 171 #ifdef CONFIG_TSEC1 172 tsec_mode = rcwh & HRCWH_TSEC1M_MASK; 173 if (tsec_mode == HRCWH_TSEC1M_IN_SGMII) 174 __ft_tsec_fixup(blob, bd, "ethernet0", TSEC1_PHY_ADDR_SGMII); 175 #endif 176 177 #ifdef CONFIG_TSEC2 178 tsec_mode = rcwh & HRCWH_TSEC2M_MASK; 179 if (tsec_mode == HRCWH_TSEC2M_IN_SGMII) 180 __ft_tsec_fixup(blob, bd, "ethernet1", TSEC2_PHY_ADDR_SGMII); 181 #endif 182 } 183 #else 184 static inline void ft_tsec_fixup(void *blob, bd_t *bd) {} 185 #endif /* defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2) */ 186 187 int board_early_init_r(void) 188 { 189 #ifdef CONFIG_PQ_MDS_PIB 190 pib_init(); 191 #endif 192 return 0; 193 } 194 195 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) 196 extern void ddr_enable_ecc(unsigned int dram_size); 197 #endif 198 int fixed_sdram(void); 199 200 phys_size_t initdram(int board_type) 201 { 202 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; 203 u32 msize = 0; 204 205 if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im) 206 return -1; 207 208 #if defined(CONFIG_SPD_EEPROM) 209 msize = spd_sdram(); 210 #else 211 msize = fixed_sdram(); 212 #endif 213 214 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) 215 /* Initialize DDR ECC byte */ 216 ddr_enable_ecc(msize * 1024 * 1024); 217 #endif 218 219 /* return total bus DDR size(bytes) */ 220 return (msize * 1024 * 1024); 221 } 222 223 #if !defined(CONFIG_SPD_EEPROM) 224 /************************************************************************* 225 * fixed sdram init -- doesn't use serial presence detect. 226 ************************************************************************/ 227 int fixed_sdram(void) 228 { 229 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; 230 u32 msize = CONFIG_SYS_DDR_SIZE * 1024 * 1024; 231 u32 msize_log2 = __ilog2(msize); 232 233 im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000; 234 im->sysconf.ddrlaw[0].ar = LBLAWAR_EN | (msize_log2 - 1); 235 236 #if (CONFIG_SYS_DDR_SIZE != 512) 237 #warning Currenly any ddr size other than 512 is not supported 238 #endif 239 im->sysconf.ddrcdr = CONFIG_SYS_DDRCDR_VALUE; 240 udelay(50000); 241 242 im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_SDRAM_CLK_CNTL; 243 udelay(1000); 244 245 im->ddr.csbnds[0].csbnds = CONFIG_SYS_DDR_CS0_BNDS; 246 im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG; 247 udelay(1000); 248 249 im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0; 250 im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1; 251 im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2; 252 im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3; 253 im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG; 254 im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2; 255 im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE; 256 im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2; 257 im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL; 258 __asm__ __volatile__("sync"); 259 udelay(1000); 260 261 im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN; 262 udelay(2000); 263 return CONFIG_SYS_DDR_SIZE; 264 } 265 #endif /*!CONFIG_SYS_SPD_EEPROM */ 266 267 int checkboard(void) 268 { 269 puts("Board: Freescale MPC837xEMDS\n"); 270 return 0; 271 } 272 273 #if defined(CONFIG_OF_BOARD_SETUP) 274 void ft_board_setup(void *blob, bd_t *bd) 275 { 276 ft_cpu_setup(blob, bd); 277 ft_tsec_fixup(blob, bd); 278 #ifdef CONFIG_PCI 279 ft_pci_setup(blob, bd); 280 #endif 281 } 282 #endif /* CONFIG_OF_BOARD_SETUP */ 283