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