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