1*50dcf89dSDirk Eibach /* 2*50dcf89dSDirk Eibach * (C) Copyright 2014 3*50dcf89dSDirk Eibach * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de 4*50dcf89dSDirk Eibach * 5*50dcf89dSDirk Eibach * SPDX-License-Identifier: GPL-2.0+ 6*50dcf89dSDirk Eibach */ 7*50dcf89dSDirk Eibach 8*50dcf89dSDirk Eibach #include <common.h> 9*50dcf89dSDirk Eibach #include <hwconfig.h> 10*50dcf89dSDirk Eibach #include <i2c.h> 11*50dcf89dSDirk Eibach #include <spi.h> 12*50dcf89dSDirk Eibach #include <libfdt.h> 13*50dcf89dSDirk Eibach #include <fdt_support.h> 14*50dcf89dSDirk Eibach #include <pci.h> 15*50dcf89dSDirk Eibach #include <mpc83xx.h> 16*50dcf89dSDirk Eibach #include <fsl_esdhc.h> 17*50dcf89dSDirk Eibach #include <asm/io.h> 18*50dcf89dSDirk Eibach #include <asm/fsl_serdes.h> 19*50dcf89dSDirk Eibach #include <asm/fsl_mpc83xx_serdes.h> 20*50dcf89dSDirk Eibach 21*50dcf89dSDirk Eibach #include "mpc8308.h" 22*50dcf89dSDirk Eibach 23*50dcf89dSDirk Eibach #include <gdsys_fpga.h> 24*50dcf89dSDirk Eibach 25*50dcf89dSDirk Eibach #include "../common/osd.h" 26*50dcf89dSDirk Eibach #include "../common/mclink.h" 27*50dcf89dSDirk Eibach #include "../common/phy.h" 28*50dcf89dSDirk Eibach 29*50dcf89dSDirk Eibach #include <pca953x.h> 30*50dcf89dSDirk Eibach #include <pca9698.h> 31*50dcf89dSDirk Eibach 32*50dcf89dSDirk Eibach #include <miiphy.h> 33*50dcf89dSDirk Eibach 34*50dcf89dSDirk Eibach DECLARE_GLOBAL_DATA_PTR; 35*50dcf89dSDirk Eibach 36*50dcf89dSDirk Eibach #define MAX_MUX_CHANNELS 2 37*50dcf89dSDirk Eibach 38*50dcf89dSDirk Eibach enum { 39*50dcf89dSDirk Eibach UNITTYPE_MAIN_SERVER = 0, 40*50dcf89dSDirk Eibach UNITTYPE_MAIN_USER = 1, 41*50dcf89dSDirk Eibach UNITTYPE_VIDEO_SERVER = 2, 42*50dcf89dSDirk Eibach UNITTYPE_VIDEO_USER = 3, 43*50dcf89dSDirk Eibach }; 44*50dcf89dSDirk Eibach 45*50dcf89dSDirk Eibach enum { 46*50dcf89dSDirk Eibach UNITTYPEPCB_DVI = 0, 47*50dcf89dSDirk Eibach UNITTYPEPCB_DP_165 = 1, 48*50dcf89dSDirk Eibach UNITTYPEPCB_DP_300 = 2, 49*50dcf89dSDirk Eibach UNITTYPEPCB_HDMI = 3, 50*50dcf89dSDirk Eibach }; 51*50dcf89dSDirk Eibach 52*50dcf89dSDirk Eibach enum { 53*50dcf89dSDirk Eibach HWVER_100 = 0, 54*50dcf89dSDirk Eibach HWVER_110 = 1, 55*50dcf89dSDirk Eibach }; 56*50dcf89dSDirk Eibach 57*50dcf89dSDirk Eibach enum { 58*50dcf89dSDirk Eibach FPGA_HWVER_200 = 0, 59*50dcf89dSDirk Eibach FPGA_HWVER_210 = 1, 60*50dcf89dSDirk Eibach }; 61*50dcf89dSDirk Eibach 62*50dcf89dSDirk Eibach enum { 63*50dcf89dSDirk Eibach COMPRESSION_NONE = 0, 64*50dcf89dSDirk Eibach COMPRESSION_TYPE1_DELTA = 1, 65*50dcf89dSDirk Eibach COMPRESSION_TYPE1_TYPE2_DELTA = 3, 66*50dcf89dSDirk Eibach }; 67*50dcf89dSDirk Eibach 68*50dcf89dSDirk Eibach enum { 69*50dcf89dSDirk Eibach AUDIO_NONE = 0, 70*50dcf89dSDirk Eibach AUDIO_TX = 1, 71*50dcf89dSDirk Eibach AUDIO_RX = 2, 72*50dcf89dSDirk Eibach AUDIO_RXTX = 3, 73*50dcf89dSDirk Eibach }; 74*50dcf89dSDirk Eibach 75*50dcf89dSDirk Eibach enum { 76*50dcf89dSDirk Eibach SYSCLK_147456 = 0, 77*50dcf89dSDirk Eibach }; 78*50dcf89dSDirk Eibach 79*50dcf89dSDirk Eibach enum { 80*50dcf89dSDirk Eibach RAM_DDR2_32 = 0, 81*50dcf89dSDirk Eibach RAM_DDR3_32 = 1, 82*50dcf89dSDirk Eibach }; 83*50dcf89dSDirk Eibach 84*50dcf89dSDirk Eibach enum { 85*50dcf89dSDirk Eibach CARRIER_SPEED_1G = 0, 86*50dcf89dSDirk Eibach CARRIER_SPEED_2_5G = 1, 87*50dcf89dSDirk Eibach }; 88*50dcf89dSDirk Eibach 89*50dcf89dSDirk Eibach enum { 90*50dcf89dSDirk Eibach MCFPGA_DONE = 1 << 0, 91*50dcf89dSDirk Eibach MCFPGA_INIT_N = 1 << 1, 92*50dcf89dSDirk Eibach MCFPGA_PROGRAM_N = 1 << 2, 93*50dcf89dSDirk Eibach MCFPGA_UPDATE_ENABLE_N = 1 << 3, 94*50dcf89dSDirk Eibach MCFPGA_RESET_N = 1 << 4, 95*50dcf89dSDirk Eibach }; 96*50dcf89dSDirk Eibach 97*50dcf89dSDirk Eibach enum { 98*50dcf89dSDirk Eibach GPIO_MDC = 1 << 14, 99*50dcf89dSDirk Eibach GPIO_MDIO = 1 << 15, 100*50dcf89dSDirk Eibach }; 101*50dcf89dSDirk Eibach 102*50dcf89dSDirk Eibach unsigned int mclink_fpgacount; 103*50dcf89dSDirk Eibach struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR; 104*50dcf89dSDirk Eibach 105*50dcf89dSDirk Eibach int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data) 106*50dcf89dSDirk Eibach { 107*50dcf89dSDirk Eibach int res; 108*50dcf89dSDirk Eibach 109*50dcf89dSDirk Eibach switch (fpga) { 110*50dcf89dSDirk Eibach case 0: 111*50dcf89dSDirk Eibach out_le16(reg, data); 112*50dcf89dSDirk Eibach break; 113*50dcf89dSDirk Eibach default: 114*50dcf89dSDirk Eibach res = mclink_send(fpga - 1, regoff, data); 115*50dcf89dSDirk Eibach if (res < 0) { 116*50dcf89dSDirk Eibach printf("mclink_send reg %02lx data %04x returned %d\n", 117*50dcf89dSDirk Eibach regoff, data, res); 118*50dcf89dSDirk Eibach return res; 119*50dcf89dSDirk Eibach } 120*50dcf89dSDirk Eibach break; 121*50dcf89dSDirk Eibach } 122*50dcf89dSDirk Eibach 123*50dcf89dSDirk Eibach return 0; 124*50dcf89dSDirk Eibach } 125*50dcf89dSDirk Eibach 126*50dcf89dSDirk Eibach int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data) 127*50dcf89dSDirk Eibach { 128*50dcf89dSDirk Eibach int res; 129*50dcf89dSDirk Eibach 130*50dcf89dSDirk Eibach switch (fpga) { 131*50dcf89dSDirk Eibach case 0: 132*50dcf89dSDirk Eibach *data = in_le16(reg); 133*50dcf89dSDirk Eibach break; 134*50dcf89dSDirk Eibach default: 135*50dcf89dSDirk Eibach if (fpga > mclink_fpgacount) 136*50dcf89dSDirk Eibach return -EINVAL; 137*50dcf89dSDirk Eibach res = mclink_receive(fpga - 1, regoff, data); 138*50dcf89dSDirk Eibach if (res < 0) { 139*50dcf89dSDirk Eibach printf("mclink_receive reg %02lx returned %d\n", 140*50dcf89dSDirk Eibach regoff, res); 141*50dcf89dSDirk Eibach return res; 142*50dcf89dSDirk Eibach } 143*50dcf89dSDirk Eibach } 144*50dcf89dSDirk Eibach 145*50dcf89dSDirk Eibach return 0; 146*50dcf89dSDirk Eibach } 147*50dcf89dSDirk Eibach 148*50dcf89dSDirk Eibach int checkboard(void) 149*50dcf89dSDirk Eibach { 150*50dcf89dSDirk Eibach char *s = getenv("serial#"); 151*50dcf89dSDirk Eibach bool hw_type_cat = pca9698_get_value(0x20, 20); 152*50dcf89dSDirk Eibach 153*50dcf89dSDirk Eibach puts("Board: "); 154*50dcf89dSDirk Eibach 155*50dcf89dSDirk Eibach printf("HRCon %s", hw_type_cat ? "CAT" : "Fiber"); 156*50dcf89dSDirk Eibach 157*50dcf89dSDirk Eibach if (s != NULL) { 158*50dcf89dSDirk Eibach puts(", serial# "); 159*50dcf89dSDirk Eibach puts(s); 160*50dcf89dSDirk Eibach } 161*50dcf89dSDirk Eibach 162*50dcf89dSDirk Eibach puts("\n"); 163*50dcf89dSDirk Eibach 164*50dcf89dSDirk Eibach return 0; 165*50dcf89dSDirk Eibach } 166*50dcf89dSDirk Eibach 167*50dcf89dSDirk Eibach static void print_fpga_info(unsigned int fpga, bool rgmii2_present) 168*50dcf89dSDirk Eibach { 169*50dcf89dSDirk Eibach u16 versions; 170*50dcf89dSDirk Eibach u16 fpga_version; 171*50dcf89dSDirk Eibach u16 fpga_features; 172*50dcf89dSDirk Eibach unsigned unit_type; 173*50dcf89dSDirk Eibach unsigned unit_type_pcb_video; 174*50dcf89dSDirk Eibach unsigned hardware_version; 175*50dcf89dSDirk Eibach unsigned feature_compression; 176*50dcf89dSDirk Eibach unsigned feature_osd; 177*50dcf89dSDirk Eibach unsigned feature_audio; 178*50dcf89dSDirk Eibach unsigned feature_sysclock; 179*50dcf89dSDirk Eibach unsigned feature_ramconfig; 180*50dcf89dSDirk Eibach unsigned feature_carrier_speed; 181*50dcf89dSDirk Eibach unsigned feature_carriers; 182*50dcf89dSDirk Eibach unsigned feature_video_channels; 183*50dcf89dSDirk Eibach 184*50dcf89dSDirk Eibach FPGA_GET_REG(fpga, versions, &versions); 185*50dcf89dSDirk Eibach FPGA_GET_REG(fpga, fpga_version, &fpga_version); 186*50dcf89dSDirk Eibach FPGA_GET_REG(fpga, fpga_features, &fpga_features); 187*50dcf89dSDirk Eibach 188*50dcf89dSDirk Eibach unit_type = (versions & 0xf000) >> 12; 189*50dcf89dSDirk Eibach unit_type_pcb_video = (versions & 0x01c0) >> 6; 190*50dcf89dSDirk Eibach feature_compression = (fpga_features & 0xe000) >> 13; 191*50dcf89dSDirk Eibach feature_osd = fpga_features & (1<<11); 192*50dcf89dSDirk Eibach feature_audio = (fpga_features & 0x0600) >> 9; 193*50dcf89dSDirk Eibach feature_sysclock = (fpga_features & 0x0180) >> 7; 194*50dcf89dSDirk Eibach feature_ramconfig = (fpga_features & 0x0060) >> 5; 195*50dcf89dSDirk Eibach feature_carrier_speed = fpga_features & (1<<4); 196*50dcf89dSDirk Eibach feature_carriers = (fpga_features & 0x000c) >> 2; 197*50dcf89dSDirk Eibach feature_video_channels = fpga_features & 0x0003; 198*50dcf89dSDirk Eibach 199*50dcf89dSDirk Eibach switch (unit_type) { 200*50dcf89dSDirk Eibach case UNITTYPE_MAIN_USER: 201*50dcf89dSDirk Eibach printf("Mainchannel"); 202*50dcf89dSDirk Eibach break; 203*50dcf89dSDirk Eibach 204*50dcf89dSDirk Eibach case UNITTYPE_VIDEO_USER: 205*50dcf89dSDirk Eibach printf("Videochannel"); 206*50dcf89dSDirk Eibach break; 207*50dcf89dSDirk Eibach 208*50dcf89dSDirk Eibach default: 209*50dcf89dSDirk Eibach printf("UnitType %d(not supported)", unit_type); 210*50dcf89dSDirk Eibach break; 211*50dcf89dSDirk Eibach } 212*50dcf89dSDirk Eibach 213*50dcf89dSDirk Eibach if (unit_type == UNITTYPE_MAIN_USER) { 214*50dcf89dSDirk Eibach hardware_version = 215*50dcf89dSDirk Eibach (!!pca9698_get_value(0x20, 24) << 0) 216*50dcf89dSDirk Eibach | (!!pca9698_get_value(0x20, 25) << 1) 217*50dcf89dSDirk Eibach | (!!pca9698_get_value(0x20, 26) << 2) 218*50dcf89dSDirk Eibach | (!!pca9698_get_value(0x20, 27) << 3) 219*50dcf89dSDirk Eibach | (!!pca9698_get_value(0x20, 28) << 4); 220*50dcf89dSDirk Eibach switch (hardware_version) { 221*50dcf89dSDirk Eibach case HWVER_100: 222*50dcf89dSDirk Eibach printf(" HW-Ver 1.00,"); 223*50dcf89dSDirk Eibach break; 224*50dcf89dSDirk Eibach 225*50dcf89dSDirk Eibach case HWVER_110: 226*50dcf89dSDirk Eibach printf(" HW-Ver 1.10,"); 227*50dcf89dSDirk Eibach break; 228*50dcf89dSDirk Eibach 229*50dcf89dSDirk Eibach default: 230*50dcf89dSDirk Eibach printf(" HW-Ver %d(not supported),", 231*50dcf89dSDirk Eibach hardware_version); 232*50dcf89dSDirk Eibach break; 233*50dcf89dSDirk Eibach } 234*50dcf89dSDirk Eibach if (rgmii2_present) 235*50dcf89dSDirk Eibach printf(" RGMII2,"); 236*50dcf89dSDirk Eibach } 237*50dcf89dSDirk Eibach 238*50dcf89dSDirk Eibach if (unit_type == UNITTYPE_VIDEO_USER) { 239*50dcf89dSDirk Eibach hardware_version = versions & 0x000f; 240*50dcf89dSDirk Eibach switch (hardware_version) { 241*50dcf89dSDirk Eibach case FPGA_HWVER_200: 242*50dcf89dSDirk Eibach printf(" HW-Ver 2.00,"); 243*50dcf89dSDirk Eibach break; 244*50dcf89dSDirk Eibach 245*50dcf89dSDirk Eibach case FPGA_HWVER_210: 246*50dcf89dSDirk Eibach printf(" HW-Ver 2.10,"); 247*50dcf89dSDirk Eibach break; 248*50dcf89dSDirk Eibach 249*50dcf89dSDirk Eibach default: 250*50dcf89dSDirk Eibach printf(" HW-Ver %d(not supported),", 251*50dcf89dSDirk Eibach hardware_version); 252*50dcf89dSDirk Eibach break; 253*50dcf89dSDirk Eibach } 254*50dcf89dSDirk Eibach } 255*50dcf89dSDirk Eibach 256*50dcf89dSDirk Eibach switch (unit_type_pcb_video) { 257*50dcf89dSDirk Eibach case UNITTYPEPCB_DVI: 258*50dcf89dSDirk Eibach printf(" DVI,"); 259*50dcf89dSDirk Eibach break; 260*50dcf89dSDirk Eibach 261*50dcf89dSDirk Eibach case UNITTYPEPCB_DP_165: 262*50dcf89dSDirk Eibach printf(" DP 165MPix/s,"); 263*50dcf89dSDirk Eibach break; 264*50dcf89dSDirk Eibach 265*50dcf89dSDirk Eibach case UNITTYPEPCB_DP_300: 266*50dcf89dSDirk Eibach printf(" DP 300MPix/s,"); 267*50dcf89dSDirk Eibach break; 268*50dcf89dSDirk Eibach 269*50dcf89dSDirk Eibach case UNITTYPEPCB_HDMI: 270*50dcf89dSDirk Eibach printf(" HDMI,"); 271*50dcf89dSDirk Eibach break; 272*50dcf89dSDirk Eibach } 273*50dcf89dSDirk Eibach 274*50dcf89dSDirk Eibach printf(" FPGA V %d.%02d\n features:", 275*50dcf89dSDirk Eibach fpga_version / 100, fpga_version % 100); 276*50dcf89dSDirk Eibach 277*50dcf89dSDirk Eibach 278*50dcf89dSDirk Eibach switch (feature_compression) { 279*50dcf89dSDirk Eibach case COMPRESSION_NONE: 280*50dcf89dSDirk Eibach printf(" no compression"); 281*50dcf89dSDirk Eibach break; 282*50dcf89dSDirk Eibach 283*50dcf89dSDirk Eibach case COMPRESSION_TYPE1_DELTA: 284*50dcf89dSDirk Eibach printf(" type1-deltacompression"); 285*50dcf89dSDirk Eibach break; 286*50dcf89dSDirk Eibach 287*50dcf89dSDirk Eibach case COMPRESSION_TYPE1_TYPE2_DELTA: 288*50dcf89dSDirk Eibach printf(" type1-deltacompression, type2-inlinecompression"); 289*50dcf89dSDirk Eibach break; 290*50dcf89dSDirk Eibach 291*50dcf89dSDirk Eibach default: 292*50dcf89dSDirk Eibach printf(" compression %d(not supported)", feature_compression); 293*50dcf89dSDirk Eibach break; 294*50dcf89dSDirk Eibach } 295*50dcf89dSDirk Eibach 296*50dcf89dSDirk Eibach printf(", %sosd", feature_osd ? "" : "no "); 297*50dcf89dSDirk Eibach 298*50dcf89dSDirk Eibach switch (feature_audio) { 299*50dcf89dSDirk Eibach case AUDIO_NONE: 300*50dcf89dSDirk Eibach printf(", no audio"); 301*50dcf89dSDirk Eibach break; 302*50dcf89dSDirk Eibach 303*50dcf89dSDirk Eibach case AUDIO_TX: 304*50dcf89dSDirk Eibach printf(", audio tx"); 305*50dcf89dSDirk Eibach break; 306*50dcf89dSDirk Eibach 307*50dcf89dSDirk Eibach case AUDIO_RX: 308*50dcf89dSDirk Eibach printf(", audio rx"); 309*50dcf89dSDirk Eibach break; 310*50dcf89dSDirk Eibach 311*50dcf89dSDirk Eibach case AUDIO_RXTX: 312*50dcf89dSDirk Eibach printf(", audio rx+tx"); 313*50dcf89dSDirk Eibach break; 314*50dcf89dSDirk Eibach 315*50dcf89dSDirk Eibach default: 316*50dcf89dSDirk Eibach printf(", audio %d(not supported)", feature_audio); 317*50dcf89dSDirk Eibach break; 318*50dcf89dSDirk Eibach } 319*50dcf89dSDirk Eibach 320*50dcf89dSDirk Eibach puts(",\n "); 321*50dcf89dSDirk Eibach 322*50dcf89dSDirk Eibach switch (feature_sysclock) { 323*50dcf89dSDirk Eibach case SYSCLK_147456: 324*50dcf89dSDirk Eibach printf("clock 147.456 MHz"); 325*50dcf89dSDirk Eibach break; 326*50dcf89dSDirk Eibach 327*50dcf89dSDirk Eibach default: 328*50dcf89dSDirk Eibach printf("clock %d(not supported)", feature_sysclock); 329*50dcf89dSDirk Eibach break; 330*50dcf89dSDirk Eibach } 331*50dcf89dSDirk Eibach 332*50dcf89dSDirk Eibach switch (feature_ramconfig) { 333*50dcf89dSDirk Eibach case RAM_DDR2_32: 334*50dcf89dSDirk Eibach printf(", RAM 32 bit DDR2"); 335*50dcf89dSDirk Eibach break; 336*50dcf89dSDirk Eibach 337*50dcf89dSDirk Eibach case RAM_DDR3_32: 338*50dcf89dSDirk Eibach printf(", RAM 32 bit DDR3"); 339*50dcf89dSDirk Eibach break; 340*50dcf89dSDirk Eibach 341*50dcf89dSDirk Eibach default: 342*50dcf89dSDirk Eibach printf(", RAM %d(not supported)", feature_ramconfig); 343*50dcf89dSDirk Eibach break; 344*50dcf89dSDirk Eibach } 345*50dcf89dSDirk Eibach 346*50dcf89dSDirk Eibach printf(", %d carrier(s) %s", feature_carriers, 347*50dcf89dSDirk Eibach feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s"); 348*50dcf89dSDirk Eibach 349*50dcf89dSDirk Eibach printf(", %d video channel(s)\n", feature_video_channels); 350*50dcf89dSDirk Eibach } 351*50dcf89dSDirk Eibach 352*50dcf89dSDirk Eibach int last_stage_init(void) 353*50dcf89dSDirk Eibach { 354*50dcf89dSDirk Eibach int slaves; 355*50dcf89dSDirk Eibach unsigned int k; 356*50dcf89dSDirk Eibach unsigned int mux_ch; 357*50dcf89dSDirk Eibach unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 }; 358*50dcf89dSDirk Eibach u16 fpga_features; 359*50dcf89dSDirk Eibach bool hw_type_cat = pca9698_get_value(0x20, 20); 360*50dcf89dSDirk Eibach bool ch0_rgmii2_present = false; 361*50dcf89dSDirk Eibach 362*50dcf89dSDirk Eibach FPGA_GET_REG(0, fpga_features, &fpga_features); 363*50dcf89dSDirk Eibach 364*50dcf89dSDirk Eibach /* Turn on Parade DP501 */ 365*50dcf89dSDirk Eibach pca9698_direction_output(0x20, 10, 1); 366*50dcf89dSDirk Eibach 367*50dcf89dSDirk Eibach ch0_rgmii2_present = !pca9698_get_value(0x20, 30); 368*50dcf89dSDirk Eibach 369*50dcf89dSDirk Eibach /* wait for FPGA done */ 370*50dcf89dSDirk Eibach for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) { 371*50dcf89dSDirk Eibach unsigned int ctr = 0; 372*50dcf89dSDirk Eibach 373*50dcf89dSDirk Eibach if (i2c_probe(mclink_controllers[k])) 374*50dcf89dSDirk Eibach continue; 375*50dcf89dSDirk Eibach 376*50dcf89dSDirk Eibach while (!(pca953x_get_val(mclink_controllers[k]) 377*50dcf89dSDirk Eibach & MCFPGA_DONE)) { 378*50dcf89dSDirk Eibach udelay(100000); 379*50dcf89dSDirk Eibach if (ctr++ > 5) { 380*50dcf89dSDirk Eibach printf("no done for mclink_controller %d\n", k); 381*50dcf89dSDirk Eibach break; 382*50dcf89dSDirk Eibach } 383*50dcf89dSDirk Eibach } 384*50dcf89dSDirk Eibach } 385*50dcf89dSDirk Eibach 386*50dcf89dSDirk Eibach if (hw_type_cat) { 387*50dcf89dSDirk Eibach miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read, 388*50dcf89dSDirk Eibach bb_miiphy_write); 389*50dcf89dSDirk Eibach for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { 390*50dcf89dSDirk Eibach if ((mux_ch == 1) && !ch0_rgmii2_present) 391*50dcf89dSDirk Eibach continue; 392*50dcf89dSDirk Eibach 393*50dcf89dSDirk Eibach setup_88e1514(bb_miiphy_buses[0].name, mux_ch); 394*50dcf89dSDirk Eibach } 395*50dcf89dSDirk Eibach } 396*50dcf89dSDirk Eibach 397*50dcf89dSDirk Eibach /* give slave-PLLs and Parade DP501 some time to be up and running */ 398*50dcf89dSDirk Eibach udelay(500000); 399*50dcf89dSDirk Eibach 400*50dcf89dSDirk Eibach mclink_fpgacount = CONFIG_SYS_MCLINK_MAX; 401*50dcf89dSDirk Eibach slaves = mclink_probe(); 402*50dcf89dSDirk Eibach mclink_fpgacount = 0; 403*50dcf89dSDirk Eibach 404*50dcf89dSDirk Eibach print_fpga_info(0, ch0_rgmii2_present); 405*50dcf89dSDirk Eibach osd_probe(0); 406*50dcf89dSDirk Eibach 407*50dcf89dSDirk Eibach if (slaves <= 0) 408*50dcf89dSDirk Eibach return 0; 409*50dcf89dSDirk Eibach 410*50dcf89dSDirk Eibach mclink_fpgacount = slaves; 411*50dcf89dSDirk Eibach 412*50dcf89dSDirk Eibach for (k = 1; k <= slaves; ++k) { 413*50dcf89dSDirk Eibach FPGA_GET_REG(k, fpga_features, &fpga_features); 414*50dcf89dSDirk Eibach 415*50dcf89dSDirk Eibach print_fpga_info(k, false); 416*50dcf89dSDirk Eibach osd_probe(k); 417*50dcf89dSDirk Eibach if (hw_type_cat) { 418*50dcf89dSDirk Eibach miiphy_register(bb_miiphy_buses[k].name, 419*50dcf89dSDirk Eibach bb_miiphy_read, bb_miiphy_write); 420*50dcf89dSDirk Eibach setup_88e1514(bb_miiphy_buses[k].name, 0); 421*50dcf89dSDirk Eibach } 422*50dcf89dSDirk Eibach } 423*50dcf89dSDirk Eibach 424*50dcf89dSDirk Eibach return 0; 425*50dcf89dSDirk Eibach } 426*50dcf89dSDirk Eibach 427*50dcf89dSDirk Eibach /* 428*50dcf89dSDirk Eibach * provide access to fpga gpios (for I2C bitbang) 429*50dcf89dSDirk Eibach * (these may look all too simple but make iocon.h much more readable) 430*50dcf89dSDirk Eibach */ 431*50dcf89dSDirk Eibach void fpga_gpio_set(unsigned int bus, int pin) 432*50dcf89dSDirk Eibach { 433*50dcf89dSDirk Eibach FPGA_SET_REG(bus, gpio.set, pin); 434*50dcf89dSDirk Eibach } 435*50dcf89dSDirk Eibach 436*50dcf89dSDirk Eibach void fpga_gpio_clear(unsigned int bus, int pin) 437*50dcf89dSDirk Eibach { 438*50dcf89dSDirk Eibach FPGA_SET_REG(bus, gpio.clear, pin); 439*50dcf89dSDirk Eibach } 440*50dcf89dSDirk Eibach 441*50dcf89dSDirk Eibach int fpga_gpio_get(unsigned int bus, int pin) 442*50dcf89dSDirk Eibach { 443*50dcf89dSDirk Eibach u16 val; 444*50dcf89dSDirk Eibach 445*50dcf89dSDirk Eibach FPGA_GET_REG(bus, gpio.read, &val); 446*50dcf89dSDirk Eibach 447*50dcf89dSDirk Eibach return val & pin; 448*50dcf89dSDirk Eibach } 449*50dcf89dSDirk Eibach 450*50dcf89dSDirk Eibach void mpc8308_init(void) 451*50dcf89dSDirk Eibach { 452*50dcf89dSDirk Eibach pca9698_direction_output(0x20, 4, 1); 453*50dcf89dSDirk Eibach } 454*50dcf89dSDirk Eibach 455*50dcf89dSDirk Eibach void mpc8308_set_fpga_reset(unsigned state) 456*50dcf89dSDirk Eibach { 457*50dcf89dSDirk Eibach pca9698_set_value(0x20, 4, state ? 0 : 1); 458*50dcf89dSDirk Eibach } 459*50dcf89dSDirk Eibach 460*50dcf89dSDirk Eibach void mpc8308_setup_hw(void) 461*50dcf89dSDirk Eibach { 462*50dcf89dSDirk Eibach immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 463*50dcf89dSDirk Eibach 464*50dcf89dSDirk Eibach /* 465*50dcf89dSDirk Eibach * set "startup-finished"-gpios 466*50dcf89dSDirk Eibach */ 467*50dcf89dSDirk Eibach setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12))); 468*50dcf89dSDirk Eibach setbits_be32(&immr->gpio[0].dat, 1 << (31-12)); 469*50dcf89dSDirk Eibach } 470*50dcf89dSDirk Eibach 471*50dcf89dSDirk Eibach int mpc8308_get_fpga_done(unsigned fpga) 472*50dcf89dSDirk Eibach { 473*50dcf89dSDirk Eibach return pca9698_get_value(0x20, 19); 474*50dcf89dSDirk Eibach } 475*50dcf89dSDirk Eibach 476*50dcf89dSDirk Eibach #ifdef CONFIG_FSL_ESDHC 477*50dcf89dSDirk Eibach int board_mmc_init(bd_t *bd) 478*50dcf89dSDirk Eibach { 479*50dcf89dSDirk Eibach immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 480*50dcf89dSDirk Eibach sysconf83xx_t *sysconf = &immr->sysconf; 481*50dcf89dSDirk Eibach 482*50dcf89dSDirk Eibach /* Enable cache snooping in eSDHC system configuration register */ 483*50dcf89dSDirk Eibach out_be32(&sysconf->sdhccr, 0x02000000); 484*50dcf89dSDirk Eibach 485*50dcf89dSDirk Eibach return fsl_esdhc_mmc_init(bd); 486*50dcf89dSDirk Eibach } 487*50dcf89dSDirk Eibach #endif 488*50dcf89dSDirk Eibach 489*50dcf89dSDirk Eibach static struct pci_region pcie_regions_0[] = { 490*50dcf89dSDirk Eibach { 491*50dcf89dSDirk Eibach .bus_start = CONFIG_SYS_PCIE1_MEM_BASE, 492*50dcf89dSDirk Eibach .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS, 493*50dcf89dSDirk Eibach .size = CONFIG_SYS_PCIE1_MEM_SIZE, 494*50dcf89dSDirk Eibach .flags = PCI_REGION_MEM, 495*50dcf89dSDirk Eibach }, 496*50dcf89dSDirk Eibach { 497*50dcf89dSDirk Eibach .bus_start = CONFIG_SYS_PCIE1_IO_BASE, 498*50dcf89dSDirk Eibach .phys_start = CONFIG_SYS_PCIE1_IO_PHYS, 499*50dcf89dSDirk Eibach .size = CONFIG_SYS_PCIE1_IO_SIZE, 500*50dcf89dSDirk Eibach .flags = PCI_REGION_IO, 501*50dcf89dSDirk Eibach }, 502*50dcf89dSDirk Eibach }; 503*50dcf89dSDirk Eibach 504*50dcf89dSDirk Eibach void pci_init_board(void) 505*50dcf89dSDirk Eibach { 506*50dcf89dSDirk Eibach immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 507*50dcf89dSDirk Eibach sysconf83xx_t *sysconf = &immr->sysconf; 508*50dcf89dSDirk Eibach law83xx_t *pcie_law = sysconf->pcielaw; 509*50dcf89dSDirk Eibach struct pci_region *pcie_reg[] = { pcie_regions_0 }; 510*50dcf89dSDirk Eibach 511*50dcf89dSDirk Eibach fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX, 512*50dcf89dSDirk Eibach FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); 513*50dcf89dSDirk Eibach 514*50dcf89dSDirk Eibach /* Deassert the resets in the control register */ 515*50dcf89dSDirk Eibach out_be32(&sysconf->pecr1, 0xE0008000); 516*50dcf89dSDirk Eibach udelay(2000); 517*50dcf89dSDirk Eibach 518*50dcf89dSDirk Eibach /* Configure PCI Express Local Access Windows */ 519*50dcf89dSDirk Eibach out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR); 520*50dcf89dSDirk Eibach out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB); 521*50dcf89dSDirk Eibach 522*50dcf89dSDirk Eibach mpc83xx_pcie_init(1, pcie_reg); 523*50dcf89dSDirk Eibach } 524*50dcf89dSDirk Eibach 525*50dcf89dSDirk Eibach ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info) 526*50dcf89dSDirk Eibach { 527*50dcf89dSDirk Eibach info->portwidth = FLASH_CFI_16BIT; 528*50dcf89dSDirk Eibach info->chipwidth = FLASH_CFI_BY16; 529*50dcf89dSDirk Eibach info->interface = FLASH_CFI_X16; 530*50dcf89dSDirk Eibach return 1; 531*50dcf89dSDirk Eibach } 532*50dcf89dSDirk Eibach 533*50dcf89dSDirk Eibach #if defined(CONFIG_OF_BOARD_SETUP) 534*50dcf89dSDirk Eibach void ft_board_setup(void *blob, bd_t *bd) 535*50dcf89dSDirk Eibach { 536*50dcf89dSDirk Eibach ft_cpu_setup(blob, bd); 537*50dcf89dSDirk Eibach fdt_fixup_dr_usb(blob, bd); 538*50dcf89dSDirk Eibach fdt_fixup_esdhc(blob, bd); 539*50dcf89dSDirk Eibach } 540*50dcf89dSDirk Eibach #endif 541*50dcf89dSDirk Eibach 542*50dcf89dSDirk Eibach /* 543*50dcf89dSDirk Eibach * FPGA MII bitbang implementation 544*50dcf89dSDirk Eibach */ 545*50dcf89dSDirk Eibach 546*50dcf89dSDirk Eibach struct fpga_mii { 547*50dcf89dSDirk Eibach unsigned fpga; 548*50dcf89dSDirk Eibach int mdio; 549*50dcf89dSDirk Eibach } fpga_mii[] = { 550*50dcf89dSDirk Eibach { 0, 1}, 551*50dcf89dSDirk Eibach { 1, 1}, 552*50dcf89dSDirk Eibach { 2, 1}, 553*50dcf89dSDirk Eibach { 3, 1}, 554*50dcf89dSDirk Eibach }; 555*50dcf89dSDirk Eibach 556*50dcf89dSDirk Eibach static int mii_dummy_init(struct bb_miiphy_bus *bus) 557*50dcf89dSDirk Eibach { 558*50dcf89dSDirk Eibach return 0; 559*50dcf89dSDirk Eibach } 560*50dcf89dSDirk Eibach 561*50dcf89dSDirk Eibach static int mii_mdio_active(struct bb_miiphy_bus *bus) 562*50dcf89dSDirk Eibach { 563*50dcf89dSDirk Eibach struct fpga_mii *fpga_mii = bus->priv; 564*50dcf89dSDirk Eibach 565*50dcf89dSDirk Eibach if (fpga_mii->mdio) 566*50dcf89dSDirk Eibach FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); 567*50dcf89dSDirk Eibach else 568*50dcf89dSDirk Eibach FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); 569*50dcf89dSDirk Eibach 570*50dcf89dSDirk Eibach return 0; 571*50dcf89dSDirk Eibach } 572*50dcf89dSDirk Eibach 573*50dcf89dSDirk Eibach static int mii_mdio_tristate(struct bb_miiphy_bus *bus) 574*50dcf89dSDirk Eibach { 575*50dcf89dSDirk Eibach struct fpga_mii *fpga_mii = bus->priv; 576*50dcf89dSDirk Eibach 577*50dcf89dSDirk Eibach FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); 578*50dcf89dSDirk Eibach 579*50dcf89dSDirk Eibach return 0; 580*50dcf89dSDirk Eibach } 581*50dcf89dSDirk Eibach 582*50dcf89dSDirk Eibach static int mii_set_mdio(struct bb_miiphy_bus *bus, int v) 583*50dcf89dSDirk Eibach { 584*50dcf89dSDirk Eibach struct fpga_mii *fpga_mii = bus->priv; 585*50dcf89dSDirk Eibach 586*50dcf89dSDirk Eibach if (v) 587*50dcf89dSDirk Eibach FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO); 588*50dcf89dSDirk Eibach else 589*50dcf89dSDirk Eibach FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO); 590*50dcf89dSDirk Eibach 591*50dcf89dSDirk Eibach fpga_mii->mdio = v; 592*50dcf89dSDirk Eibach 593*50dcf89dSDirk Eibach return 0; 594*50dcf89dSDirk Eibach } 595*50dcf89dSDirk Eibach 596*50dcf89dSDirk Eibach static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v) 597*50dcf89dSDirk Eibach { 598*50dcf89dSDirk Eibach u16 gpio; 599*50dcf89dSDirk Eibach struct fpga_mii *fpga_mii = bus->priv; 600*50dcf89dSDirk Eibach 601*50dcf89dSDirk Eibach FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio); 602*50dcf89dSDirk Eibach 603*50dcf89dSDirk Eibach *v = ((gpio & GPIO_MDIO) != 0); 604*50dcf89dSDirk Eibach 605*50dcf89dSDirk Eibach return 0; 606*50dcf89dSDirk Eibach } 607*50dcf89dSDirk Eibach 608*50dcf89dSDirk Eibach static int mii_set_mdc(struct bb_miiphy_bus *bus, int v) 609*50dcf89dSDirk Eibach { 610*50dcf89dSDirk Eibach struct fpga_mii *fpga_mii = bus->priv; 611*50dcf89dSDirk Eibach 612*50dcf89dSDirk Eibach if (v) 613*50dcf89dSDirk Eibach FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC); 614*50dcf89dSDirk Eibach else 615*50dcf89dSDirk Eibach FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC); 616*50dcf89dSDirk Eibach 617*50dcf89dSDirk Eibach return 0; 618*50dcf89dSDirk Eibach } 619*50dcf89dSDirk Eibach 620*50dcf89dSDirk Eibach static int mii_delay(struct bb_miiphy_bus *bus) 621*50dcf89dSDirk Eibach { 622*50dcf89dSDirk Eibach udelay(1); 623*50dcf89dSDirk Eibach 624*50dcf89dSDirk Eibach return 0; 625*50dcf89dSDirk Eibach } 626*50dcf89dSDirk Eibach 627*50dcf89dSDirk Eibach struct bb_miiphy_bus bb_miiphy_buses[] = { 628*50dcf89dSDirk Eibach { 629*50dcf89dSDirk Eibach .name = "board0", 630*50dcf89dSDirk Eibach .init = mii_dummy_init, 631*50dcf89dSDirk Eibach .mdio_active = mii_mdio_active, 632*50dcf89dSDirk Eibach .mdio_tristate = mii_mdio_tristate, 633*50dcf89dSDirk Eibach .set_mdio = mii_set_mdio, 634*50dcf89dSDirk Eibach .get_mdio = mii_get_mdio, 635*50dcf89dSDirk Eibach .set_mdc = mii_set_mdc, 636*50dcf89dSDirk Eibach .delay = mii_delay, 637*50dcf89dSDirk Eibach .priv = &fpga_mii[0], 638*50dcf89dSDirk Eibach }, 639*50dcf89dSDirk Eibach { 640*50dcf89dSDirk Eibach .name = "board1", 641*50dcf89dSDirk Eibach .init = mii_dummy_init, 642*50dcf89dSDirk Eibach .mdio_active = mii_mdio_active, 643*50dcf89dSDirk Eibach .mdio_tristate = mii_mdio_tristate, 644*50dcf89dSDirk Eibach .set_mdio = mii_set_mdio, 645*50dcf89dSDirk Eibach .get_mdio = mii_get_mdio, 646*50dcf89dSDirk Eibach .set_mdc = mii_set_mdc, 647*50dcf89dSDirk Eibach .delay = mii_delay, 648*50dcf89dSDirk Eibach .priv = &fpga_mii[1], 649*50dcf89dSDirk Eibach }, 650*50dcf89dSDirk Eibach { 651*50dcf89dSDirk Eibach .name = "board2", 652*50dcf89dSDirk Eibach .init = mii_dummy_init, 653*50dcf89dSDirk Eibach .mdio_active = mii_mdio_active, 654*50dcf89dSDirk Eibach .mdio_tristate = mii_mdio_tristate, 655*50dcf89dSDirk Eibach .set_mdio = mii_set_mdio, 656*50dcf89dSDirk Eibach .get_mdio = mii_get_mdio, 657*50dcf89dSDirk Eibach .set_mdc = mii_set_mdc, 658*50dcf89dSDirk Eibach .delay = mii_delay, 659*50dcf89dSDirk Eibach .priv = &fpga_mii[2], 660*50dcf89dSDirk Eibach }, 661*50dcf89dSDirk Eibach { 662*50dcf89dSDirk Eibach .name = "board3", 663*50dcf89dSDirk Eibach .init = mii_dummy_init, 664*50dcf89dSDirk Eibach .mdio_active = mii_mdio_active, 665*50dcf89dSDirk Eibach .mdio_tristate = mii_mdio_tristate, 666*50dcf89dSDirk Eibach .set_mdio = mii_set_mdio, 667*50dcf89dSDirk Eibach .get_mdio = mii_get_mdio, 668*50dcf89dSDirk Eibach .set_mdc = mii_set_mdc, 669*50dcf89dSDirk Eibach .delay = mii_delay, 670*50dcf89dSDirk Eibach .priv = &fpga_mii[3], 671*50dcf89dSDirk Eibach }, 672*50dcf89dSDirk Eibach }; 673*50dcf89dSDirk Eibach 674*50dcf89dSDirk Eibach int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) / 675*50dcf89dSDirk Eibach sizeof(bb_miiphy_buses[0]); 676