static void io_reflect(unsigned int fpga) { u16 buffer[128]; unsigned int k = 0; unsigned int n; u16 rx_tx_status; FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status); while (rx_tx_status & STATE_RX_DATA_AVAILABLE) { FPGA_GET_REG(fpga, ep.receive_data, &buffer[k++]); if (rx_tx_status & STATE_RX_DATA_LAST) break; FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status); } if (!k) return; for (n = 0; n < k; ++n) FPGA_SET_REG(fpga, ep.transmit_data, buffer[n]); FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER); tx_ctr++; }
int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned int fpga; unsigned int size; unsigned int rate = 0; if (argc < 3) return CMD_RET_USAGE; /* * FPGA is specified since argc > 2 */ fpga = simple_strtoul(argv[1], NULL, 10); /* * packet size is specified since argc > 2 */ size = simple_strtoul(argv[2], NULL, 10); /* * If another parameter, it is the test rate in packets per second. */ if (argc > 3) rate = simple_strtoul(argv[3], NULL, 10); /* enable receive path */ FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE); /* set device address to dummy 1*/ FPGA_SET_REG(fpga, ep.device_address, 1); rx_ctr = 0; tx_ctr = 0; err_ctr = 0; while (1) { u16 top_int; u16 rx_tx_status; FPGA_GET_REG(fpga, top_interrupt, &top_int); FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status); io_check_status(fpga, rx_tx_status, false); if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS) io_send(fpga, size); if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) io_receive(fpga); if (rate) { if (ctrlc()) break; udelay(1000000 / rate); if (!(tx_ctr % rate)) printf("d %lld, tx %llu, rx %llu, err %llu\n", tx_ctr - rx_ctr, tx_ctr, rx_ctr, err_ctr); } } return 0; }
/* * FPGA io-endpoint reflector * * Syntax: * ioreflect {fpga} {reportrate} */ int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned int fpga; unsigned int rate = 0; unsigned long long last_seen = 0; if (argc < 2) return CMD_RET_USAGE; fpga = simple_strtoul(argv[1], NULL, 10); /* * If another parameter, it is the report rate in packets. */ if (argc > 2) rate = simple_strtoul(argv[2], NULL, 10); /* enable receive path */ FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE); /* set device address to dummy 1*/ FPGA_SET_REG(fpga, ep.device_address, 1); rx_ctr = 0; tx_ctr = 0; err_ctr = 0; while (1) { u16 top_int; u16 rx_tx_status; FPGA_GET_REG(fpga, top_interrupt, &top_int); FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status); io_check_status(fpga, rx_tx_status, true); if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) && (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)) io_reflect(fpga); if (rate) { if (!(tx_ctr % rate) && (tx_ctr != last_seen)) printf("refl %llu, err %llu\n", tx_ctr, err_ctr); last_seen = tx_ctr; } if (ctrlc()) break; } return 0; }
void fpga_control_set(unsigned int bus, int pin) { u16 val; FPGA_GET_REG(bus, control, &val); FPGA_SET_REG(bus, control, val | pin); }
void fpga_control_clear(uint bus, int pin) { u16 val; FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, control, &val); FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val & ~pin); }
void fpga_control_clear(unsigned int bus, int pin) { u16 val; FPGA_GET_REG(bus, control, &val); FPGA_SET_REG(bus, control, val & ~pin); }
int fpga_gpio_get(uint bus, int pin) { u16 val; FPGA_GET_REG(bus >= 4 ? (bus - 4) : bus, gpio.read, &val); return val & pin; }
int fpga_gpio_get(unsigned int bus, int pin) { u16 val; FPGA_GET_REG(bus, gpio.read, &val); return val & pin; }
bool ioep_fpga_has_osd(unsigned int fpga) { u16 fpga_features; unsigned feature_osd; FPGA_GET_REG(0, fpga_features, &fpga_features); feature_osd = fpga_features & (1<<11); return feature_osd; }
static void io_send(unsigned int fpga, unsigned int size) { unsigned int k; struct io_generic_packet packet = { .source_address = 1, .packet_type = 1, .packet_length = size, }; u16 *p = (u16 *)&packet; for (k = 0; k < sizeof(packet) / 2; ++k) FPGA_SET_REG(fpga, ep.transmit_data, *p++); for (k = 0; k < (size + 1) / 2; ++k) FPGA_SET_REG(fpga, ep.transmit_data, k); FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER); tx_ctr++; } static void io_receive(unsigned int fpga) { unsigned int k = 0; u16 rx_tx_status; FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status); while (rx_tx_status & STATE_RX_DATA_AVAILABLE) { u16 rx; if (rx_tx_status & STATE_RX_DATA_LAST) rx_ctr++; FPGA_GET_REG(fpga, ep.receive_data, &rx); FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status); ++k; } }
static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v) { u16 gpio; struct fpga_mii *fpga_mii = bus->priv; FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio); *v = ((gpio & GPIO_MDIO) != 0); return 0; }
static int ihs_mdio_idle(struct mii_dev *bus) { struct ihs_mdio_info *info = bus->priv; u16 val; unsigned int ctr = 0; do { FPGA_GET_REG(info->fpga, mdio.control, &val); udelay(100); if (ctr++ > 10) return -1; } while (!(val & (1 << 12))); return 0; }
static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr, int regnum) { struct ihs_mdio_info *info = bus->priv; u16 val; ihs_mdio_idle(bus); FPGA_SET_REG(info->fpga, mdio.control, ((addr & 0x1f) << 5) | (regnum & 0x1f) | (2 << 10)); /* wait for rx data available */ udelay(100); FPGA_GET_REG(info->fpga, mdio.rx_data, &val); return val; }
static void print_fpga_info(void) { u16 versions; u16 fpga_version; u16 fpga_features; unsigned unit_type; unsigned hardware_version; unsigned feature_channels; unsigned feature_expansion; FPGA_GET_REG(0, versions, &versions); FPGA_GET_REG(0, fpga_version, &fpga_version); FPGA_GET_REG(0, fpga_features, &fpga_features); unit_type = (versions & 0xf000) >> 12; hardware_version = versions & 0x000f; feature_channels = fpga_features & 0x007f; feature_expansion = fpga_features & (1<<15); puts("FPGA: "); switch (unit_type) { case UNITTYPE_CCD_SWITCH: printf("CCD-Switch"); break; default: printf("UnitType %d(not supported)", unit_type); break; } switch (hardware_version) { case HWVER_100: printf(" HW-Ver 1.00\n"); break; case HWVER_110: printf(" HW-Ver 1.10\n"); break; case HWVER_121: printf(" HW-Ver 1.21\n"); break; case HWVER_122: printf(" HW-Ver 1.22\n"); break; default: printf(" HW-Ver %d(not supported)\n", hardware_version); break; } printf(" FPGA V %d.%02d, features:", fpga_version / 100, fpga_version % 100); printf(" %d channel(s)", feature_channels); printf(", expansion %ssupported\n", feature_expansion ? "" : "un"); }
int last_stage_init(void) { int slaves; uint k; uchar mclink_controllers[] = { 0x3c, 0x3d, 0x3e }; u16 fpga_features; bool hw_type_cat = pca9698_get_value(0x20, 20); bool ch0_rgmii2_present; FPGA_GET_REG(0, fpga_features, &fpga_features); /* Turn on Parade DP501 */ pca9698_direction_output(0x20, 10, 1); pca9698_direction_output(0x20, 11, 1); ch0_rgmii2_present = !pca9698_get_value(0x20, 30); /* wait for FPGA done, then reset FPGA */ for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) { uint ctr = 0; if (i2c_probe(mclink_controllers[k])) continue; while (!(pca953x_get_val(mclink_controllers[k]) & MCFPGA_DONE)) { mdelay(100); if (ctr++ > 5) { printf("no done for mclink_controller %u\n", k); break; } } pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0); pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0); udelay(10); pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, MCFPGA_RESET_N); } if (hw_type_cat) { uint mux_ch; int retval; struct mii_dev *mdiodev = mdio_alloc(); if (!mdiodev) return -ENOMEM; strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN); mdiodev->read = bb_miiphy_read; mdiodev->write = bb_miiphy_write; retval = mdio_register(mdiodev); if (retval < 0) return retval; for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { if ((mux_ch == 1) && !ch0_rgmii2_present) continue; setup_88e1514(bb_miiphy_buses[0].name, mux_ch); } } /* give slave-PLLs and Parade DP501 some time to be up and running */ mdelay(500); mclink_fpgacount = CONFIG_SYS_MCLINK_MAX; slaves = mclink_probe(); mclink_fpgacount = 0; ioep_fpga_print_info(0); osd_probe(0); #ifdef CONFIG_SYS_OSD_DH osd_probe(4); #endif if (slaves <= 0) return 0; mclink_fpgacount = slaves; for (k = 1; k <= slaves; ++k) { FPGA_GET_REG(k, fpga_features, &fpga_features); ioep_fpga_print_info(k); osd_probe(k); #ifdef CONFIG_SYS_OSD_DH osd_probe(k + 4); #endif if (hw_type_cat) { int retval; struct mii_dev *mdiodev = mdio_alloc(); if (!mdiodev) return -ENOMEM; strncpy(mdiodev->name, bb_miiphy_buses[k].name, MDIO_NAME_LEN); mdiodev->read = bb_miiphy_read; mdiodev->write = bb_miiphy_write; retval = mdio_register(mdiodev); if (retval < 0) return retval; setup_88e1514(bb_miiphy_buses[k].name, 0); } } for (k = 0; k < ARRAY_SIZE(hrcon_fans); ++k) { i2c_set_bus_num(hrcon_fans[k].bus); init_fan_controller(hrcon_fans[k].addr); } return 0; }
void ioep_fpga_print_info(unsigned int fpga) { u16 versions; u16 fpga_version; u16 fpga_features; unsigned unit_type; unsigned unit_type_pcb_video; unsigned feature_compression; unsigned feature_osd; unsigned feature_audio; unsigned feature_sysclock; unsigned feature_ramconfig; unsigned feature_carrier_speed; unsigned feature_carriers; unsigned feature_video_channels; FPGA_GET_REG(fpga, versions, &versions); FPGA_GET_REG(fpga, fpga_version, &fpga_version); FPGA_GET_REG(fpga, fpga_features, &fpga_features); unit_type = (versions & 0xf000) >> 12; unit_type_pcb_video = (versions & 0x01c0) >> 6; feature_compression = (fpga_features & 0xe000) >> 13; feature_osd = fpga_features & (1<<11); feature_audio = (fpga_features & 0x0600) >> 9; feature_sysclock = (fpga_features & 0x0180) >> 7; feature_ramconfig = (fpga_features & 0x0060) >> 5; feature_carrier_speed = fpga_features & (1<<4); feature_carriers = (fpga_features & 0x000c) >> 2; feature_video_channels = fpga_features & 0x0003; switch (unit_type) { case UNITTYPE_MAIN_SERVER: case UNITTYPE_MAIN_USER: printf("Mainchannel"); break; case UNITTYPE_VIDEO_SERVER: case UNITTYPE_VIDEO_USER: printf("Videochannel"); break; default: printf("UnitType %d(not supported)", unit_type); break; } switch (unit_type) { case UNITTYPE_MAIN_SERVER: case UNITTYPE_VIDEO_SERVER: printf(" Server"); if (versions & (1<<4)) printf(" UC"); break; case UNITTYPE_MAIN_USER: case UNITTYPE_VIDEO_USER: printf(" User"); break; default: break; } if (versions & (1<<5)) printf(" Fiber"); else printf(" CAT"); switch (unit_type_pcb_video) { case UNITTYPEPCB_DVI: printf(" DVI,"); break; case UNITTYPEPCB_DP_165: printf(" DP 165MPix/s,"); break; case UNITTYPEPCB_DP_300: printf(" DP 300MPix/s,"); break; case UNITTYPEPCB_HDMI: printf(" HDMI,"); break; } printf(" FPGA V %d.%02d\n features:", fpga_version / 100, fpga_version % 100); switch (feature_compression) { case COMPRESSION_NONE: printf(" no compression"); break; case COMPRESSION_TYPE_1: printf(" compression type1(delta)"); break; case COMPRESSION_TYPE_1_2: printf(" compression type1(delta), type2(inline)"); break; case COMPRESSION_TYPE_1_2_3: printf(" compression type1(delta), type2(inline), type3(intempo)"); break; default: printf(" compression %d(not supported)", feature_compression); break; } printf(", %sosd", feature_osd ? "" : "no "); switch (feature_audio) { case AUDIO_NONE: printf(", no audio"); break; case AUDIO_TX: printf(", audio tx"); break; case AUDIO_RX: printf(", audio rx"); break; case AUDIO_RXTX: printf(", audio rx+tx"); break; default: printf(", audio %d(not supported)", feature_audio); break; } puts(",\n "); switch (feature_sysclock) { case SYSCLK_147456: printf("clock 147.456 MHz"); break; default: printf("clock %d(not supported)", feature_sysclock); break; } switch (feature_ramconfig) { case RAM_DDR2_32: printf(", RAM 32 bit DDR2"); break; case RAM_DDR3_32: printf(", RAM 32 bit DDR3"); break; case RAM_DDR3_48: printf(", RAM 48 bit DDR3"); break; default: printf(", RAM %d(not supported)", feature_ramconfig); break; } printf(", %d carrier(s) %s", feature_carriers, feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s"); printf(", %d video channel(s)\n", feature_video_channels); }
static void print_fpga_info(unsigned dev) { u16 versions; u16 fpga_version; u16 fpga_features; int fpga_state = get_fpga_state(dev); unsigned unit_type; unsigned hardware_version; unsigned feature_channels; unsigned feature_expansion; FPGA_GET_REG(dev, versions, &versions); FPGA_GET_REG(dev, fpga_version, &fpga_version); FPGA_GET_REG(dev, fpga_features, &fpga_features); printf("FPGA%d: ", dev); if (fpga_state & FPGA_STATE_PLATFORM) printf("(legacy) "); if (fpga_state & FPGA_STATE_DONE_FAILED) { printf(" done timed out\n"); return; } if (fpga_state & FPGA_STATE_REFLECTION_FAILED) { printf(" refelectione test failed\n"); return; } unit_type = (versions & 0xf000) >> 12; hardware_version = versions & 0x000f; feature_channels = fpga_features & 0x007f; feature_expansion = fpga_features & (1<<15); switch (unit_type) { case UNITTYPE_CCD_SWITCH: printf("CCD-Switch"); break; default: printf("UnitType %d(not supported)", unit_type); break; } switch (hardware_version) { case HWVER_100: printf(" HW-Ver 1.00\n"); break; case HWVER_110: printf(" HW-Ver 1.10\n"); break; default: printf(" HW-Ver %d(not supported)\n", hardware_version); break; } printf(" FPGA V %d.%02d, features:", fpga_version / 100, fpga_version % 100); printf(" %d channel(s)", feature_channels); printf(", expansion %ssupported\n", feature_expansion ? "" : "un"); }
static void print_fpga_info(unsigned int fpga, bool rgmii2_present) { u16 versions; u16 fpga_version; u16 fpga_features; unsigned unit_type; unsigned hardware_version; unsigned feature_compression; unsigned feature_osd; unsigned feature_audio; unsigned feature_sysclock; unsigned feature_ramconfig; unsigned feature_carrier_speed; unsigned feature_carriers; unsigned feature_video_channels; int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM; FPGA_GET_REG(0, versions, &versions); FPGA_GET_REG(0, fpga_version, &fpga_version); FPGA_GET_REG(0, fpga_features, &fpga_features); unit_type = (versions & 0xf000) >> 12; feature_compression = (fpga_features & 0xe000) >> 13; feature_osd = fpga_features & (1<<11); feature_audio = (fpga_features & 0x0600) >> 9; feature_sysclock = (fpga_features & 0x0180) >> 7; feature_ramconfig = (fpga_features & 0x0060) >> 5; feature_carrier_speed = fpga_features & (1<<4); feature_carriers = (fpga_features & 0x000c) >> 2; feature_video_channels = fpga_features & 0x0003; if (legacy) printf("legacy "); switch (unit_type) { case UNITTYPE_MAIN_USER: printf("Mainchannel"); break; case UNITTYPE_VIDEO_USER: printf("Videochannel"); break; default: printf("UnitType %d(not supported)", unit_type); break; } if (unit_type == UNITTYPE_MAIN_USER) { if (legacy) hardware_version = (in_le16((void *)LATCH2_BASE)>>8) & 0x0f; else hardware_version = (!!pca9698_get_value(0x20, 24) << 0) | (!!pca9698_get_value(0x20, 25) << 1) | (!!pca9698_get_value(0x20, 26) << 2) | (!!pca9698_get_value(0x20, 27) << 3); switch (hardware_version) { case HWVER_100: printf(" HW-Ver 1.00,"); break; case HWVER_104: printf(" HW-Ver 1.04,"); break; case HWVER_110: printf(" HW-Ver 1.10,"); break; case HWVER_120: printf(" HW-Ver 1.20-1.21,"); break; case HWVER_200: printf(" HW-Ver 2.00,"); break; case HWVER_210: printf(" HW-Ver 2.10,"); break; case HWVER_220: printf(" HW-Ver 2.20,"); break; case HWVER_230: printf(" HW-Ver 2.30,"); break; default: printf(" HW-Ver %d(not supported),", hardware_version); break; } if (rgmii2_present) printf(" RGMII2,"); }
int last_stage_init(void) { unsigned int k; unsigned int fpga; int failed = 0; char str_phys[] = "Setup PHYs -"; char str_serdes[] = "Start SERDES blocks"; char str_channels[] = "Start FPGA channels"; char str_locks[] = "Verify SERDES locks"; char str_hicb[] = "Verify HICB status"; char str_status[] = "Verify PHY status -"; char slash[] = "\\|/-\\|/-"; print_fpga_info(0); print_fpga_info(1); /* setup Gbit PHYs */ puts("TRANS: "); puts(str_phys); miiphy_register(CONFIG_SYS_GBIT_MII_BUSNAME, bb_miiphy_read, bb_miiphy_write); for (k = 0; k < 32; ++k) { configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k); putc('\b'); putc(slash[k % 8]); } miiphy_register(CONFIG_SYS_GBIT_MII1_BUSNAME, bb_miiphy_read, bb_miiphy_write); for (k = 0; k < 32; ++k) { configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k); putc('\b'); putc(slash[k % 8]); } blank_string(strlen(str_phys)); /* take fpga serdes blocks out of reset */ puts(str_serdes); udelay(500000); FPGA_SET_REG(0, quad_serdes_reset, 0); FPGA_SET_REG(1, quad_serdes_reset, 0); blank_string(strlen(str_serdes)); /* take channels out of reset */ puts(str_channels); udelay(500000); for (fpga = 0; fpga < 2; ++fpga) { for (k = 0; k < 32; ++k) FPGA_SET_REG(fpga, ch[k].config_int, 0); } blank_string(strlen(str_channels)); /* verify channels serdes lock */ puts(str_locks); udelay(500000); for (fpga = 0; fpga < 2; ++fpga) { for (k = 0; k < 32; ++k) { u16 status; FPGA_GET_REG(k, ch[k].status_int, &status); if (!(status & (1 << 4))) { failed = 1; printf("fpga %d channel %d: no serdes lock\n", fpga, k); } /* reset events */ FPGA_SET_REG(fpga, ch[k].status_int, 0); } } blank_string(strlen(str_locks)); /* verify hicb_status */ puts(str_hicb); for (fpga = 0; fpga < 2; ++fpga) { for (k = 0; k < 32; ++k) { u16 status; FPGA_GET_REG(k, hicb_ch[k].status_int, &status); if (status) printf("fpga %d hicb %d: hicb status %04x\n", fpga, k, status); /* reset events */ FPGA_SET_REG(fpga, hicb_ch[k].status_int, 0); } } blank_string(strlen(str_hicb)); /* verify phy status */ puts(str_status); for (k = 0; k < 32; ++k) { if (verify_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k)) { printf("verify baseboard phy %d failed\n", k); failed = 1; } putc('\b'); putc(slash[k % 8]); } for (k = 0; k < 32; ++k) { if (verify_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k)) { printf("verify extensionboard phy %d failed\n", k); failed = 1; } putc('\b'); putc(slash[k % 8]); } blank_string(strlen(str_status)); printf("Starting 64 channels %s\n", failed ? "failed" : "ok"); return 0; }