1 /* 2 * (C) Copyright 2014 3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <hwconfig.h> 10 #include <i2c.h> 11 #include <spi.h> 12 #include <libfdt.h> 13 #include <fdt_support.h> 14 #include <pci.h> 15 #include <mpc83xx.h> 16 #include <fsl_esdhc.h> 17 #include <asm/io.h> 18 #include <asm/fsl_serdes.h> 19 #include <asm/fsl_mpc83xx_serdes.h> 20 21 #include "mpc8308.h" 22 23 #include <gdsys_fpga.h> 24 25 #include "../common/ioep-fpga.h" 26 #include "../common/osd.h" 27 #include "../common/mclink.h" 28 #include "../common/phy.h" 29 30 #include <pca953x.h> 31 #include <pca9698.h> 32 33 #include <miiphy.h> 34 35 DECLARE_GLOBAL_DATA_PTR; 36 37 #define MAX_MUX_CHANNELS 2 38 39 enum { 40 MCFPGA_DONE = 1 << 0, 41 MCFPGA_INIT_N = 1 << 1, 42 MCFPGA_PROGRAM_N = 1 << 2, 43 MCFPGA_UPDATE_ENABLE_N = 1 << 3, 44 MCFPGA_RESET_N = 1 << 4, 45 }; 46 47 enum { 48 GPIO_MDC = 1 << 14, 49 GPIO_MDIO = 1 << 15, 50 }; 51 52 unsigned int mclink_fpgacount; 53 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; 54 55 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data) 56 { 57 int res; 58 59 switch (fpga) { 60 case 0: 61 out_le16(reg, data); 62 break; 63 default: 64 res = mclink_send(fpga - 1, regoff, data); 65 if (res < 0) { 66 printf("mclink_send reg %02lx data %04x returned %d\n", 67 regoff, data, res); 68 return res; 69 } 70 break; 71 } 72 73 return 0; 74 } 75 76 int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data) 77 { 78 int res; 79 80 switch (fpga) { 81 case 0: 82 *data = in_le16(reg); 83 break; 84 default: 85 if (fpga > mclink_fpgacount) 86 return -EINVAL; 87 res = mclink_receive(fpga - 1, regoff, data); 88 if (res < 0) { 89 printf("mclink_receive reg %02lx returned %d\n", 90 regoff, res); 91 return res; 92 } 93 } 94 95 return 0; 96 } 97 98 int checkboard(void) 99 { 100 char *s = getenv("serial#"); 101 bool hw_type_cat = pca9698_get_value(0x20, 20); 102 103 puts("Board: "); 104 105 printf("HRCon %s", hw_type_cat ? "CAT" : "Fiber"); 106 107 if (s != NULL) { 108 puts(", serial# "); 109 puts(s); 110 } 111 112 puts("\n"); 113 114 return 0; 115 } 116 117 int last_stage_init(void) 118 { 119 int slaves; 120 unsigned int k; 121 unsigned int mux_ch; 122 unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e }; 123 u16 fpga_features; 124 bool hw_type_cat = pca9698_get_value(0x20, 20); 125 bool ch0_rgmii2_present = false; 126 127 FPGA_GET_REG(0, fpga_features, &fpga_features); 128 129 /* Turn on Parade DP501 */ 130 pca9698_direction_output(0x20, 10, 1); 131 pca9698_direction_output(0x20, 11, 1); 132 133 ch0_rgmii2_present = !pca9698_get_value(0x20, 30); 134 135 /* wait for FPGA done, then reset FPGA */ 136 for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) { 137 unsigned int ctr = 0; 138 139 if (i2c_probe(mclink_controllers[k])) 140 continue; 141 142 while (!(pca953x_get_val(mclink_controllers[k]) 143 & MCFPGA_DONE)) { 144 udelay(100000); 145 if (ctr++ > 5) { 146 printf("no done for mclink_controller %d\n", k); 147 break; 148 } 149 } 150 151 pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0); 152 pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0); 153 udelay(10); 154 pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 155 MCFPGA_RESET_N); 156 } 157 158 if (hw_type_cat) { 159 miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read, 160 bb_miiphy_write); 161 for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { 162 if ((mux_ch == 1) && !ch0_rgmii2_present) 163 continue; 164 165 setup_88e1514(bb_miiphy_buses[0].name, mux_ch); 166 } 167 } 168 169 /* give slave-PLLs and Parade DP501 some time to be up and running */ 170 udelay(500000); 171 172 mclink_fpgacount = CONFIG_SYS_MCLINK_MAX; 173 slaves = mclink_probe(); 174 mclink_fpgacount = 0; 175 176 ioep_fpga_print_info(0); 177 osd_probe(0); 178 #ifdef CONFIG_SYS_OSD_DH 179 osd_probe(4); 180 #endif 181 182 if (slaves <= 0) 183 return 0; 184 185 mclink_fpgacount = slaves; 186 187 for (k = 1; k <= slaves; ++k) { 188 FPGA_GET_REG(k, fpga_features, &fpga_features); 189 190 ioep_fpga_print_info(k); 191 osd_probe(k); 192 #ifdef CONFIG_SYS_OSD_DH 193 osd_probe(k + 4); 194 #endif 195 if (hw_type_cat) { 196 miiphy_register(bb_miiphy_buses[k].name, 197 bb_miiphy_read, bb_miiphy_write); 198 setup_88e1514(bb_miiphy_buses[k].name, 0); 199 } 200 } 201 202 return 0; 203 } 204 205 /* 206 * provide access to fpga gpios and controls (for I2C bitbang) 207 * (these may look all too simple but make iocon.h much more readable) 208 */ 209 void fpga_gpio_set(unsigned int bus, int pin) 210 { 211 FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.set, pin); 212 } 213 214 void fpga_gpio_clear(unsigned int bus, int pin) 215 { 216 FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.clear, pin); 217 } 218 219 int fpga_gpio_get(unsigned int bus, int pin) 220 { 221 u16 val; 222 223 FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, gpio.read, &val); 224 225 return val & pin; 226 } 227 228 void fpga_control_set(unsigned int bus, int pin) 229 { 230 u16 val; 231 232 FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val); 233 FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val | pin); 234 } 235 236 void fpga_control_clear(unsigned int bus, int pin) 237 { 238 u16 val; 239 240 FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val); 241 FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val & ~pin); 242 } 243 244 void mpc8308_init(void) 245 { 246 pca9698_direction_output(0x20, 4, 1); 247 } 248 249 void mpc8308_set_fpga_reset(unsigned state) 250 { 251 pca9698_set_value(0x20, 4, state ? 0 : 1); 252 } 253 254 void mpc8308_setup_hw(void) 255 { 256 immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 257 258 /* 259 * set "startup-finished"-gpios 260 */ 261 setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12))); 262 setbits_be32(&immr->gpio[0].dat, 1 << (31-12)); 263 } 264 265 int mpc8308_get_fpga_done(unsigned fpga) 266 { 267 return pca9698_get_value(0x20, 19); 268 } 269 270 #ifdef CONFIG_FSL_ESDHC 271 int board_mmc_init(bd_t *bd) 272 { 273 immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 274 sysconf83xx_t *sysconf = &immr->sysconf; 275 276 /* Enable cache snooping in eSDHC system configuration register */ 277 out_be32(&sysconf->sdhccr, 0x02000000); 278 279 return fsl_esdhc_mmc_init(bd); 280 } 281 #endif 282 283 static struct pci_region pcie_regions_0[] = { 284 { 285 .bus_start = CONFIG_SYS_PCIE1_MEM_BASE, 286 .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS, 287 .size = CONFIG_SYS_PCIE1_MEM_SIZE, 288 .flags = PCI_REGION_MEM, 289 }, 290 { 291 .bus_start = CONFIG_SYS_PCIE1_IO_BASE, 292 .phys_start = CONFIG_SYS_PCIE1_IO_PHYS, 293 .size = CONFIG_SYS_PCIE1_IO_SIZE, 294 .flags = PCI_REGION_IO, 295 }, 296 }; 297 298 void pci_init_board(void) 299 { 300 immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 301 sysconf83xx_t *sysconf = &immr->sysconf; 302 law83xx_t *pcie_law = sysconf->pcielaw; 303 struct pci_region *pcie_reg[] = { pcie_regions_0 }; 304 305 fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX, 306 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 307 308 /* Deassert the resets in the control register */ 309 out_be32(&sysconf->pecr1, 0xE0008000); 310 udelay(2000); 311 312 /* Configure PCI Express Local Access Windows */ 313 out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR); 314 out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB); 315 316 mpc83xx_pcie_init(1, pcie_reg); 317 } 318 319 ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info) 320 { 321 info->portwidth = FLASH_CFI_16BIT; 322 info->chipwidth = FLASH_CFI_BY16; 323 info->interface = FLASH_CFI_X16; 324 return 1; 325 } 326 327 #if defined(CONFIG_OF_BOARD_SETUP) 328 int ft_board_setup(void *blob, bd_t *bd) 329 { 330 ft_cpu_setup(blob, bd); 331 fdt_fixup_dr_usb(blob, bd); 332 fdt_fixup_esdhc(blob, bd); 333 334 return 0; 335 } 336 #endif 337 338 /* 339 * FPGA MII bitbang implementation 340 */ 341 342 struct fpga_mii { 343 unsigned fpga; 344 int mdio; 345 } fpga_mii[] = { 346 { 0, 1}, 347 { 1, 1}, 348 { 2, 1}, 349 { 3, 1}, 350 }; 351 352 static int mii_dummy_init(struct bb_miiphy_bus *bus) 353 { 354 return 0; 355 } 356 357 static int mii_mdio_active(struct bb_miiphy_bus *bus) 358 { 359 struct fpga_mii *fpga_mii = bus->priv; 360 361 if (fpga_mii->mdio) 362 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); 363 else 364 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); 365 366 return 0; 367 } 368 369 static int mii_mdio_tristate(struct bb_miiphy_bus *bus) 370 { 371 struct fpga_mii *fpga_mii = bus->priv; 372 373 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); 374 375 return 0; 376 } 377 378 static int mii_set_mdio(struct bb_miiphy_bus *bus, int v) 379 { 380 struct fpga_mii *fpga_mii = bus->priv; 381 382 if (v) 383 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); 384 else 385 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); 386 387 fpga_mii->mdio = v; 388 389 return 0; 390 } 391 392 static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v) 393 { 394 u16 gpio; 395 struct fpga_mii *fpga_mii = bus->priv; 396 397 FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio); 398 399 *v = ((gpio & GPIO_MDIO) != 0); 400 401 return 0; 402 } 403 404 static int mii_set_mdc(struct bb_miiphy_bus *bus, int v) 405 { 406 struct fpga_mii *fpga_mii = bus->priv; 407 408 if (v) 409 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC); 410 else 411 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC); 412 413 return 0; 414 } 415 416 static int mii_delay(struct bb_miiphy_bus *bus) 417 { 418 udelay(1); 419 420 return 0; 421 } 422 423 struct bb_miiphy_bus bb_miiphy_buses[] = { 424 { 425 .name = "board0", 426 .init = mii_dummy_init, 427 .mdio_active = mii_mdio_active, 428 .mdio_tristate = mii_mdio_tristate, 429 .set_mdio = mii_set_mdio, 430 .get_mdio = mii_get_mdio, 431 .set_mdc = mii_set_mdc, 432 .delay = mii_delay, 433 .priv = &fpga_mii[0], 434 }, 435 { 436 .name = "board1", 437 .init = mii_dummy_init, 438 .mdio_active = mii_mdio_active, 439 .mdio_tristate = mii_mdio_tristate, 440 .set_mdio = mii_set_mdio, 441 .get_mdio = mii_get_mdio, 442 .set_mdc = mii_set_mdc, 443 .delay = mii_delay, 444 .priv = &fpga_mii[1], 445 }, 446 { 447 .name = "board2", 448 .init = mii_dummy_init, 449 .mdio_active = mii_mdio_active, 450 .mdio_tristate = mii_mdio_tristate, 451 .set_mdio = mii_set_mdio, 452 .get_mdio = mii_get_mdio, 453 .set_mdc = mii_set_mdc, 454 .delay = mii_delay, 455 .priv = &fpga_mii[2], 456 }, 457 { 458 .name = "board3", 459 .init = mii_dummy_init, 460 .mdio_active = mii_mdio_active, 461 .mdio_tristate = mii_mdio_tristate, 462 .set_mdio = mii_set_mdio, 463 .get_mdio = mii_get_mdio, 464 .set_mdc = mii_set_mdc, 465 .delay = mii_delay, 466 .priv = &fpga_mii[3], 467 }, 468 }; 469 470 int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) / 471 sizeof(bb_miiphy_buses[0]); 472