1 /* 2 * Copyright (C) 2007,2010 Freescale Semiconductor, Inc. 3 * Dave Liu <daveliu@freescale.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <hwconfig.h> 10 #include <i2c.h> 11 #include <asm/io.h> 12 #include <asm/fsl_mpc83xx_serdes.h> 13 #include <spd_sdram.h> 14 #include <tsec.h> 15 #include <libfdt.h> 16 #include <fdt_support.h> 17 #include <fsl_esdhc.h> 18 #include <fsl_mdio.h> 19 #include <phy.h> 20 #include "pci.h" 21 #include "../common/pq-mds-pib.h" 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 int board_early_init_f(void) 26 { 27 u8 *bcsr = (u8 *)CONFIG_SYS_BCSR; 28 29 /* Enable flash write */ 30 bcsr[0x9] &= ~0x04; 31 /* Clear all of the interrupt of BCSR */ 32 bcsr[0xe] = 0xff; 33 34 #ifdef CONFIG_FSL_SERDES 35 immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 36 u32 spridr = in_be32(&immr->sysconf.spridr); 37 38 /* we check only part num, and don't look for CPU revisions */ 39 switch (PARTID_NO_E(spridr)) { 40 case SPR_8377: 41 fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA, 42 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 43 break; 44 case SPR_8378: 45 fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SGMII, 46 FSL_SERDES_CLK_125, FSL_SERDES_VDD_1V); 47 break; 48 case SPR_8379: 49 fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA, 50 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 51 fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_SATA, 52 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 53 break; 54 default: 55 printf("serdes not configured: unknown CPU part number: " 56 "%04x\n", spridr >> 16); 57 break; 58 } 59 #endif /* CONFIG_FSL_SERDES */ 60 return 0; 61 } 62 63 #ifdef CONFIG_FSL_ESDHC 64 int board_mmc_init(bd_t *bd) 65 { 66 struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; 67 u8 *bcsr = (u8 *)CONFIG_SYS_BCSR; 68 69 if (!hwconfig("esdhc")) 70 return 0; 71 72 /* Set SPI_SD, SER_SD, and IRQ4_WP so that SD signals go through */ 73 bcsr[0xc] |= 0x4c; 74 75 /* Set proper bits in SICR to allow SD signals through */ 76 clrsetbits_be32(&im->sysconf.sicrl, SICRL_USB_B, SICRL_USB_B_SD); 77 clrsetbits_be32(&im->sysconf.sicrh, SICRH_GPIO2_E | SICRH_SPI, 78 SICRH_GPIO2_E_SD | SICRH_SPI_SD); 79 80 return fsl_esdhc_mmc_init(bd); 81 } 82 #endif 83 84 #if defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2) 85 int board_eth_init(bd_t *bd) 86 { 87 struct fsl_pq_mdio_info mdio_info; 88 struct tsec_info_struct tsec_info[2]; 89 struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; 90 u32 rcwh = in_be32(&im->reset.rcwh); 91 u32 tsec_mode; 92 int num = 0; 93 94 /* New line after Net: */ 95 printf("\n"); 96 97 #ifdef CONFIG_TSEC1 98 SET_STD_TSEC_INFO(tsec_info[num], 1); 99 100 printf(CONFIG_TSEC1_NAME ": "); 101 102 tsec_mode = rcwh & HRCWH_TSEC1M_MASK; 103 if (tsec_mode == HRCWH_TSEC1M_IN_RGMII) { 104 printf("RGMII\n"); 105 /* this is default, no need to fixup */ 106 } else if (tsec_mode == HRCWH_TSEC1M_IN_SGMII) { 107 printf("SGMII\n"); 108 tsec_info[num].phyaddr = TSEC1_PHY_ADDR_SGMII; 109 tsec_info[num].flags = TSEC_GIGABIT; 110 } else { 111 printf("unsupported PHY type\n"); 112 } 113 num++; 114 #endif 115 #ifdef CONFIG_TSEC2 116 SET_STD_TSEC_INFO(tsec_info[num], 2); 117 118 printf(CONFIG_TSEC2_NAME ": "); 119 120 tsec_mode = rcwh & HRCWH_TSEC2M_MASK; 121 if (tsec_mode == HRCWH_TSEC2M_IN_RGMII) { 122 printf("RGMII\n"); 123 /* this is default, no need to fixup */ 124 } else if (tsec_mode == HRCWH_TSEC2M_IN_SGMII) { 125 printf("SGMII\n"); 126 tsec_info[num].phyaddr = TSEC2_PHY_ADDR_SGMII; 127 tsec_info[num].flags = TSEC_GIGABIT; 128 } else { 129 printf("unsupported PHY type\n"); 130 } 131 num++; 132 #endif 133 134 mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; 135 mdio_info.name = DEFAULT_MII_NAME; 136 fsl_pq_mdio_init(bd, &mdio_info); 137 138 return tsec_eth_init(bd, tsec_info, num); 139 } 140 141 static void __ft_tsec_fixup(void *blob, bd_t *bd, const char *alias, 142 int phy_addr) 143 { 144 const u32 *ph; 145 int off; 146 int err; 147 148 off = fdt_path_offset(blob, alias); 149 if (off < 0) { 150 printf("WARNING: could not find %s alias: %s.\n", alias, 151 fdt_strerror(off)); 152 return; 153 } 154 155 err = fdt_fixup_phy_connection(blob, off, PHY_INTERFACE_MODE_SGMII); 156 157 if (err) { 158 printf("WARNING: could not set phy-connection-type for %s: " 159 "%s.\n", alias, fdt_strerror(err)); 160 return; 161 } 162 163 ph = (u32 *)fdt_getprop(blob, off, "phy-handle", 0); 164 if (!ph) { 165 printf("WARNING: could not get phy-handle for %s.\n", 166 alias); 167 return; 168 } 169 170 off = fdt_node_offset_by_phandle(blob, *ph); 171 if (off < 0) { 172 printf("WARNING: could not get phy node for %s: %s\n", alias, 173 fdt_strerror(off)); 174 return; 175 } 176 177 phy_addr = cpu_to_fdt32(phy_addr); 178 err = fdt_setprop(blob, off, "reg", &phy_addr, sizeof(phy_addr)); 179 if (err < 0) { 180 printf("WARNING: could not set phy node's reg for %s: " 181 "%s.\n", alias, fdt_strerror(err)); 182 return; 183 } 184 } 185 186 static void ft_tsec_fixup(void *blob, bd_t *bd) 187 { 188 struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; 189 u32 rcwh = in_be32(&im->reset.rcwh); 190 u32 tsec_mode; 191 192 #ifdef CONFIG_TSEC1 193 tsec_mode = rcwh & HRCWH_TSEC1M_MASK; 194 if (tsec_mode == HRCWH_TSEC1M_IN_SGMII) 195 __ft_tsec_fixup(blob, bd, "ethernet0", TSEC1_PHY_ADDR_SGMII); 196 #endif 197 198 #ifdef CONFIG_TSEC2 199 tsec_mode = rcwh & HRCWH_TSEC2M_MASK; 200 if (tsec_mode == HRCWH_TSEC2M_IN_SGMII) 201 __ft_tsec_fixup(blob, bd, "ethernet1", TSEC2_PHY_ADDR_SGMII); 202 #endif 203 } 204 #else 205 static inline void ft_tsec_fixup(void *blob, bd_t *bd) {} 206 #endif /* defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2) */ 207 208 int board_early_init_r(void) 209 { 210 #ifdef CONFIG_PQ_MDS_PIB 211 pib_init(); 212 #endif 213 return 0; 214 } 215 216 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 217 extern void ddr_enable_ecc(unsigned int dram_size); 218 #endif 219 int fixed_sdram(void); 220 221 int dram_init(void) 222 { 223 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; 224 u32 msize = 0; 225 226 if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im) 227 return -ENXIO; 228 229 #if defined(CONFIG_SPD_EEPROM) 230 msize = spd_sdram(); 231 #else 232 msize = fixed_sdram(); 233 #endif 234 235 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) 236 /* Initialize DDR ECC byte */ 237 ddr_enable_ecc(msize * 1024 * 1024); 238 #endif 239 240 /* return total bus DDR size(bytes) */ 241 gd->ram_size = msize * 1024 * 1024; 242 243 return 0; 244 } 245 246 #if !defined(CONFIG_SPD_EEPROM) 247 /************************************************************************* 248 * fixed sdram init -- doesn't use serial presence detect. 249 ************************************************************************/ 250 int fixed_sdram(void) 251 { 252 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; 253 u32 msize = CONFIG_SYS_DDR_SIZE * 1024 * 1024; 254 u32 msize_log2 = __ilog2(msize); 255 256 im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000; 257 im->sysconf.ddrlaw[0].ar = LBLAWAR_EN | (msize_log2 - 1); 258 259 #if (CONFIG_SYS_DDR_SIZE != 512) 260 #warning Currenly any ddr size other than 512 is not supported 261 #endif 262 im->sysconf.ddrcdr = CONFIG_SYS_DDRCDR_VALUE; 263 udelay(50000); 264 265 im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_SDRAM_CLK_CNTL; 266 udelay(1000); 267 268 im->ddr.csbnds[0].csbnds = CONFIG_SYS_DDR_CS0_BNDS; 269 im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG; 270 udelay(1000); 271 272 im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0; 273 im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1; 274 im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2; 275 im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3; 276 im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG; 277 im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2; 278 im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE; 279 im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2; 280 im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL; 281 __asm__ __volatile__("sync"); 282 udelay(1000); 283 284 im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN; 285 udelay(2000); 286 return CONFIG_SYS_DDR_SIZE; 287 } 288 #endif /*!CONFIG_SYS_SPD_EEPROM */ 289 290 int checkboard(void) 291 { 292 puts("Board: Freescale MPC837xEMDS\n"); 293 return 0; 294 } 295 296 #ifdef CONFIG_PCI 297 int board_pci_host_broken(void) 298 { 299 struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; 300 const u32 rcw_mask = HRCWH_PCI1_ARBITER_ENABLE | HRCWH_PCI_HOST; 301 302 /* It's always OK in case of external arbiter. */ 303 if (hwconfig_subarg_cmp("pci", "arbiter", "external")) 304 return 0; 305 306 if ((in_be32(&im->reset.rcwh) & rcw_mask) != rcw_mask) 307 return 1; 308 309 return 0; 310 } 311 312 static void ft_pci_fixup(void *blob, bd_t *bd) 313 { 314 const char *status = "broken (no arbiter)"; 315 int off; 316 int err; 317 318 off = fdt_path_offset(blob, "pci0"); 319 if (off < 0) { 320 printf("WARNING: could not find pci0 alias: %s.\n", 321 fdt_strerror(off)); 322 return; 323 } 324 325 err = fdt_setprop(blob, off, "status", status, strlen(status) + 1); 326 if (err) { 327 printf("WARNING: could not set status for pci0: %s.\n", 328 fdt_strerror(err)); 329 return; 330 } 331 } 332 #endif 333 334 #if defined(CONFIG_OF_BOARD_SETUP) 335 int ft_board_setup(void *blob, bd_t *bd) 336 { 337 ft_cpu_setup(blob, bd); 338 ft_tsec_fixup(blob, bd); 339 fsl_fdt_fixup_dr_usb(blob, bd); 340 fdt_fixup_esdhc(blob, bd); 341 #ifdef CONFIG_PCI 342 ft_pci_setup(blob, bd); 343 if (board_pci_host_broken()) 344 ft_pci_fixup(blob, bd); 345 ft_pcie_fixup(blob, bd); 346 #endif 347 348 return 0; 349 } 350 #endif /* CONFIG_OF_BOARD_SETUP */ 351