diff --git a/utils/Makefile b/utils/Makefile index 978815183..ba95285a8 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -16,6 +16,7 @@ BIN = mqnic-config BIN += mqnic-dump BIN += mqnic-fw BIN += mqnic-bmc +BIN += mqnic-xcvr BIN += perout GENDEPFLAGS = -MD -MP -MF .$(@F).d @@ -44,6 +45,9 @@ mqnic-fw: mqnic-fw.o flash.o flash_spi.o flash_bpi.o bitfile.o $(LIBMQNIC) mqnic-bmc: mqnic-bmc.o $(LIBMQNIC) $(CC) $(ALL_CFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) +mqnic-xcvr: mqnic-xcvr.o $(LIBMQNIC) drp.o xcvr_gt.o xcvr_gthe3.o xcvr_gtye3.o xcvr_gthe4.o xcvr_gtye4.o + $(CC) $(ALL_CFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) + perout: perout.o timespec.o $(CC) $(ALL_CFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) diff --git a/utils/drp.c b/utils/drp.c new file mode 100644 index 000000000..6b78fa04d --- /dev/null +++ b/utils/drp.c @@ -0,0 +1,78 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include +#include + +int drp_rb_reg_read(const struct mqnic_reg_block *rb, uint32_t addr, uint32_t *val) +{ + mqnic_reg_write32(rb->regs, 0x14, addr); + mqnic_reg_write32(rb->regs, 0x10, 0x00000001); + mqnic_reg_read32(rb->regs, 0x10); + if ((mqnic_reg_read32(rb->regs, 0x10) & 0x00000101) != 0) + return -1; + *val = mqnic_reg_read32(rb->regs, 0x1C); + return 0; +} + +int drp_rb_reg_write(const struct mqnic_reg_block *rb, uint32_t addr, uint32_t val) +{ + mqnic_reg_write32(rb->regs, 0x14, addr); + mqnic_reg_write32(rb->regs, 0x18, val); + mqnic_reg_write32(rb->regs, 0x10, 0x00000003); + mqnic_reg_read32(rb->regs, 0x10); + if ((mqnic_reg_read32(rb->regs, 0x10) & 0x00000101) != 0) + return -1; + return 0; +} + +static int drp_rb_reg_if_read32(const struct mqnic_reg_if *reg, ptrdiff_t offset, uint32_t *value) +{ + return drp_rb_reg_read((const struct mqnic_reg_block *)reg->priv, offset, value); +} + +static int drp_rb_reg_if_write32(const struct mqnic_reg_if *reg, ptrdiff_t offset, uint32_t value) +{ + return drp_rb_reg_write((const struct mqnic_reg_block *)reg->priv, offset, value); +} + +static const struct mqnic_reg_if_ops drp_rb_reg_if_ops = { + .read32 = drp_rb_reg_if_read32, + .write32 = drp_rb_reg_if_write32 +}; + +void drp_rb_reg_if_init(struct mqnic_reg_if *reg, struct mqnic_reg_block *rb) +{ + reg->priv = rb; + reg->ops = &drp_rb_reg_if_ops; +} diff --git a/utils/drp.h b/utils/drp.h new file mode 100644 index 000000000..97992dae2 --- /dev/null +++ b/utils/drp.h @@ -0,0 +1,45 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#ifndef DRP_H +#define DRP_H + +#include +#include + +int drp_rb_reg_read(const struct mqnic_reg_block *rb, uint32_t addr, uint32_t *val); +int drp_rb_reg_write(const struct mqnic_reg_block *rb, uint32_t addr, uint32_t val); + +void drp_rb_reg_if_init(struct mqnic_reg_if *reg, struct mqnic_reg_block *rb); + +#endif /* DRP_H */ diff --git a/utils/mqnic-xcvr.c b/utils/mqnic-xcvr.c new file mode 100644 index 000000000..9b4a388ce --- /dev/null +++ b/utils/mqnic-xcvr.c @@ -0,0 +1,442 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include +#include +#include +#include + +#include +#include "xcvr_gtye4.h" + +static void usage(char *name) +{ + fprintf(stderr, + "usage: %s [options]\n" + " -d name device to open (/dev/mqnic0)\n" + " -i number GT channel index, default 0\n" + " -m number GT channel mask\n" + " -p preset Load channel preset\n" + " -r Read registers\n" + " -t Reset channels\n" + " -c file Run eye scan and write CSV\n", + name); +} + +int main(int argc, char *argv[]) +{ + char *name; + int opt; + int ret = 0; + + char *device = NULL; + struct mqnic *dev; + int channel_mask = 1; + int channel_preset = 0; + char *channel_preset_str = ""; + int channel_read_regs = 0; + int channel_reset = 0; + + char *csv_file_name = NULL; + + name = strrchr(argv[0], '/'); + name = name ? 1+name : argv[0]; + + while ((opt = getopt(argc, argv, "d:i:m:p:rtc:h?")) != EOF) + { + switch (opt) + { + case 'd': + device = optarg; + break; + case 'i': + channel_mask = 1 << atoi(optarg); + break; + case 'm': + channel_mask = strtol(optarg, 0, 0); + break; + case 'p': + channel_preset_str = optarg; + break; + case 'r': + channel_read_regs = 1; + break; + case 't': + channel_reset = 1; + break; + case 'c': + csv_file_name = optarg; + break; + case 'h': + case '?': + usage(name); + return 0; + default: + usage(name); + return -1; + } + } + + if (!device) + { + fprintf(stderr, "Device not specified\n"); + usage(name); + return -1; + } + + dev = mqnic_open(device); + + if (!dev) + { + fprintf(stderr, "Failed to open device\n"); + return -1; + } + + if (dev->pci_device_path[0]) + { + char *ptr = strrchr(dev->pci_device_path, '/'); + if (ptr) + printf("PCIe ID: %s\n", ptr+1); + } + + printf("Device-level register blocks:\n"); + for (struct mqnic_reg_block *rb = dev->rb_list; rb->type && rb->version; rb++) + printf(" type 0x%08x (v %d.%d.%d.%d)\n", rb->type, rb->version >> 24, + (rb->version >> 16) & 0xff, (rb->version >> 8) & 0xff, rb->version & 0xff); + + mqnic_print_fw_id(dev); + + struct gt_ch *ch; + struct gt_quad *quad; + struct gt_quad *gt_quads[16]; + int num_quads = 0; + + printf("Enumerate transceivers\n"); + for (int k = 0; k < 16; k++) + { + struct mqnic_reg_block *rb; + + rb = mqnic_find_reg_block(dev->rb_list, 0x0000C150, 0x00000100, k); + + if (!rb) + break; + + printf("Found DRP interface %d\n", k); + + quad = gt_create_quad_from_drp_rb(rb); + + if (!quad) + continue; + + quad->index = num_quads; + gt_quads[num_quads++] = quad; + + printf("Quad type: %s (0x%04x)\n", quad->type, quad->gt_type); + printf("Channel count: %d\n", quad->ch_count); + + for (int n = 0; n < quad->ch_count; n++) + { + printf("%d: %s channel: quad %d channel %d\n", quad->index*4+n, quad->type, quad->index, n); + } + + if (num_quads >= 16) + break; + } + + if (strlen(channel_preset_str)) + { + if (strcmp("10g_dfe", channel_preset_str) == 0) + channel_preset = GT_PRESET_10G_DFE; + if (strcmp("10g_lpm", channel_preset_str) == 0) + channel_preset = GT_PRESET_10G_LPM; + if (strcmp("25g_dfe", channel_preset_str) == 0) + channel_preset = GT_PRESET_25G_DFE; + if (strcmp("25g_lpm", channel_preset_str) == 0) + channel_preset = GT_PRESET_25G_LPM; + + if (!channel_preset) + { + fprintf(stderr, "Unknown preset\n"); + ret = -1; + goto err; + } + } + + for (int qi = 0; qi < num_quads; qi++) + { + quad = gt_quads[qi]; + for (int ci = 0; ci < quad->ch_count; ci++) + { + int index = qi*4 + ci; + const uint32_t *presets = {0}; + ch = &quad->ch[ci]; + + if ((channel_mask & (1 << index)) == 0) + continue; + + printf("Processing channel %d\n", index); + + if (gt_ch_get_available_presets(ch, &presets) == 0) + { + printf("Supported presets:"); + + while (*presets) + { + switch (*presets) + { + case GT_PRESET_10G_DFE: + printf(" 10g_dfe"); + break; + case GT_PRESET_10G_LPM: + printf(" 10g_lpm"); + break; + case GT_PRESET_25G_DFE: + printf(" 25g_dfe"); + break; + case GT_PRESET_25G_LPM: + printf(" 25g_lpm"); + break; + } + presets++; + } + + printf("\n"); + } + else + { + fprintf(stderr, "Failed to read presets\n"); + } + + if (channel_read_regs) + { + printf("PLL registers\n"); + + for (int k = 0; k <= 0xB0; k++) + { + uint32_t val; + gt_pll_reg_read(ch->pll, k, &val); + printf("0x%04x: 0x%04x\n", k, val); + } + + printf("Channel registers\n"); + + for (int k = 0; k <= 0x28C; k++) + { + uint32_t val; + gt_ch_reg_read(ch, k, &val); + printf("0x%04x: 0x%04x\n", k, val); + } + } + + if (channel_preset) + { + printf("Loading preset %s on channel %d\n", channel_preset_str, index); + gt_ch_load_preset(ch, channel_preset); + } + + if (channel_reset) + { + printf("Resetting channel %d\n", index); + gt_ch_rx_reset(ch); + gt_ch_tx_reset(ch); + } + } + } + + if (csv_file_name) + { + struct gt_eyescan_params params; + struct gt_eyescan_point point; + int done; + char csv_base_name[PATH_MAX]; + char csv_name[PATH_MAX]; + FILE *csv_file; + FILE *csv_files[16*4]; + char *ptr; + + uint32_t data_width; + uint32_t int_data_width; + + time_t cur_time; + struct tm *tm_info; + char datestr[32]; + + printf("Run eye scan\n"); + + params.target_bit_count = 1ULL << 30; + params.h_range = 0; + params.h_start = -32; + params.h_stop = 32; + params.h_step = 2; + params.v_range = 0; + params.v_start = -120; + params.v_stop = 120; + params.v_step = 6; + + // strip .csv extension + snprintf(csv_base_name, sizeof(csv_base_name), "%s", csv_file_name); + ptr = strstr(csv_base_name, ".csv"); + + if (ptr && ptr-csv_base_name == strlen(csv_base_name)-4) + *ptr = 0; + + // time string + time(&cur_time); + tm_info = localtime(&cur_time); + strftime(datestr, sizeof(datestr), "%F %T", tm_info); + + for (int qi = 0; qi < num_quads; qi++) + { + quad = gt_quads[qi]; + for (int ci = 0; ci < quad->ch_count; ci++) + { + int index = qi*4 + ci; + ch = &quad->ch[ci]; + + if ((channel_mask & (1 << index)) == 0) + continue; + + snprintf(csv_name, sizeof(csv_name), "%s_%d.csv", csv_base_name, index); + + printf("Measuring channel %d eye to '%s'\n", index, csv_name); + + ret = gt_ch_eyescan_start(ch, ¶ms); + if (ret < 0) + { + fprintf(stderr, "Failed to start eye scan on channel %d\n", index); + goto err; + } + + csv_file = fopen(csv_name, "w"); + + if (!csv_file) + { + fprintf(stderr, "Failed to open file\n"); + ret = -1; + goto err; + } + + csv_files[index] = csv_file; + + fprintf(csv_file, "#eyescan\n"); + fprintf(csv_file, "#date,'%s'\n", datestr); + + fprintf(csv_file, "#fpga_id,0x%08x\n", dev->fpga_id); + fprintf(csv_file, "#fw_id,0x%08x\n", dev->fw_id); + fprintf(csv_file, "#fw_version,'%d.%d.%d.%d'\n", dev->fw_ver >> 24, + (dev->fw_ver >> 16) & 0xff, + (dev->fw_ver >> 8) & 0xff, + dev->fw_ver & 0xff); + fprintf(csv_file, "#board_id,0x%08x\n", dev->board_id); + fprintf(csv_file, "#board_version,'%d.%d.%d.%d'\n", dev->board_ver >> 24, + (dev->board_ver >> 16) & 0xff, + (dev->board_ver >> 8) & 0xff, + dev->board_ver & 0xff); + fprintf(csv_file, "#build_date,'%s UTC'\n", dev->build_date_str); + fprintf(csv_file, "#git_hash,'%08x'\n", dev->git_hash); + fprintf(csv_file, "#release_info,'%08x'\n", dev->rel_info); + + fprintf(csv_file, "#channel_index,%d\n", index); + fprintf(csv_file, "#channel_type,%s\n", ch->quad->type); + fprintf(csv_file, "#quad,%d\n", ch->quad->index); + fprintf(csv_file, "#channel,%d\n", ch->index); + + gt_ch_get_rx_data_width(ch, &data_width); + gt_ch_get_rx_int_data_width(ch, &int_data_width); + + fprintf(csv_file, "#data_width,%d\n", data_width); + fprintf(csv_file, "#int_data_width,%d\n", int_data_width); + fprintf(csv_file, "#target_bit_count,%lu\n", params.target_bit_count); + fprintf(csv_file, "#h_range,%d\n", params.h_range); + fprintf(csv_file, "#h_start,%d\n", params.h_start); + fprintf(csv_file, "#h_stop,%d\n", params.h_stop); + fprintf(csv_file, "#h_step,%d\n", params.h_step); + fprintf(csv_file, "#v_range,%d\n", params.v_range); + fprintf(csv_file, "#v_start,%d\n", params.v_start); + fprintf(csv_file, "#v_stop,%d\n", params.v_stop); + fprintf(csv_file, "#v_step,%d\n", params.v_step); + fprintf(csv_file, "h_offset,v_offset,ut_sign,bit_count,error_count\n"); + + fflush(csv_file); + } + } + + done = 0; + while (!done) + { + done = 1; + for (int qi = 0; qi < num_quads; qi++) + { + quad = gt_quads[qi]; + for (int ci = 0; ci < quad->ch_count; ci++) + { + int index = qi*4 + ci; + ch = &quad->ch[ci]; + + if ((channel_mask & (1 << index)) == 0) + continue; + + ret = gt_ch_eyescan_step(ch, &point); + if (ret < 0) + { + fprintf(stderr, "Eye scan failed on channel %d\n", index); + goto err; + } + if (ret == 1) + { + // new point + printf("Channel %d point x %d, y %d\n", index, point.x, point.y); + + fprintf(csv_files[index], "%d,%d,%d,%lu,%lu\n", point.x, point.y, point.ut_sign, point.bit_count, point.error_count); + fflush(csv_files[index]); + + done = 0; + } + if (ret == 2) + { + // acquiring + done = 0; + } + } + } + } + + printf("Done\n"); + } + +err: + + mqnic_close(dev); + + return ret; +} diff --git a/utils/xcvr_gt.c b/utils/xcvr_gt.c new file mode 100644 index 000000000..5c20f69e8 --- /dev/null +++ b/utils/xcvr_gt.c @@ -0,0 +1,315 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include +#include "drp.h" +#include "xcvr_gt.h" + +#include "xcvr_gthe3.h" +#include "xcvr_gtye3.h" +#include "xcvr_gthe4.h" +#include "xcvr_gtye4.h" + +#include + +int gt_pll_reg_read(struct gt_pll *pll, uint32_t addr, uint32_t *val) +{ + if (!pll) + return -1; + + return mqnic_reg_if_read32(&pll->quad->reg, addr | (1 << 19), val); +} + +int gt_pll_reg_read_masked(struct gt_pll *pll, uint32_t addr, uint32_t *val, uint32_t mask, uint32_t shift) +{ + int ret = 0; + uint32_t v; + + ret = gt_pll_reg_read(pll, addr, &v); + if (ret) + return ret; + + *val = (v & mask) >> shift; + return 0; +} + +int gt_pll_reg_write(struct gt_pll *pll, uint32_t addr, uint32_t val) +{ + if (!pll) + return -1; + + return mqnic_reg_if_write32(&pll->quad->reg, addr | (1 << 19), val); +} + +int gt_pll_reg_write_masked(struct gt_pll *pll, uint32_t addr, uint32_t val, uint32_t mask, uint32_t shift) +{ + int ret = 0; + uint32_t old_val; + + ret = gt_pll_reg_read(pll, addr, &old_val); + if (ret) + return ret; + + return gt_pll_reg_write(pll, addr, ((val << shift) & mask) | (old_val & ~mask)); +} + +int gt_pll_reg_write_multiple(struct gt_pll *pll, const struct gt_reg_val *vals) +{ + int ret = 0; + const struct gt_reg_val *val = vals; + + while (val && val->mask) + { + ret = gt_pll_reg_write_masked(pll, val->addr, val->value, val->mask, val->shift); + if (ret) + return ret; + val++; + } + + return 0; +} + +int gt_ch_reg_read(struct gt_ch *ch, uint32_t addr, uint32_t *val) +{ + if (!ch) + return -1; + + return mqnic_reg_if_read32(&ch->quad->reg, addr | (ch->index << 17), val); +} + +int gt_ch_reg_read_masked(struct gt_ch *ch, uint32_t addr, uint32_t *val, uint32_t mask, uint32_t shift) +{ + int ret = 0; + uint32_t v; + + ret = gt_ch_reg_read(ch, addr, &v); + if (ret) + return ret; + + *val = (v & mask) >> shift; + return 0; +} + +int gt_ch_reg_write(struct gt_ch *ch, uint32_t addr, uint32_t val) +{ + if (!ch) + return -1; + + return mqnic_reg_if_write32(&ch->quad->reg, addr | (ch->index << 17), val); +} + +int gt_ch_reg_write_masked(struct gt_ch *ch, uint32_t addr, uint32_t val, uint32_t mask, uint32_t shift) +{ + int ret = 0; + uint32_t old_val; + + ret = gt_ch_reg_read(ch, addr, &old_val); + if (ret) + return ret; + + return gt_ch_reg_write(ch, addr, ((val << shift) & mask) | (old_val & ~mask)); +} + +int gt_ch_reg_write_multiple(struct gt_ch *ch, const struct gt_reg_val *vals) +{ + int ret = 0; + const struct gt_reg_val *val = vals; + + while (val && val->mask) + { + ret = gt_ch_reg_write_masked(ch, val->addr, val->value, val->mask, val->shift); + if (ret) + return ret; + val++; + } + + return 0; +} + +struct gt_quad *gt_create_quad_from_drp_rb(struct mqnic_reg_block *rb) +{ + struct gt_quad *quad = calloc(1, sizeof(struct gt_quad)); + drp_rb_reg_if_init(&quad->reg, rb); + quad->pll.quad = quad; + + uint32_t info = mqnic_reg_read32(rb->regs, 0x0C); + + quad->ch_count = info & 0xff; + quad->gt_type = info >> 16; + quad->type = "Unknown"; + + switch (quad->gt_type) { + case 0x0802: + quad->ops = >he3_gt_quad_ops; + break; + case 0x0803: + quad->ops = >ye3_gt_quad_ops; + break; + case 0x0902: + quad->ops = >he4_gt_quad_ops; + break; + case 0x0903: + quad->ops = >ye4_gt_quad_ops; + break; + default: + goto err; + } + + if (!quad->ops || !quad->ops->init) + goto err; + + if (quad->ops->init(quad)) + goto err; + + return quad; + +err: + gt_free_quad(quad); + return NULL; +} + +void gt_free_quad(struct gt_quad *quad){ + free(quad); +} + +int gt_ch_get_tx_reset(struct gt_ch *ch, uint32_t *val) +{ + if (!ch || !ch->ops || !ch->ops->get_tx_reset) + return -1; + + return ch->ops->get_tx_reset(ch, val); +} + +int gt_ch_set_tx_reset(struct gt_ch *ch, uint32_t val) +{ + if (!ch || !ch->ops || !ch->ops->set_tx_reset) + return -1; + + return ch->ops->set_tx_reset(ch, val); +} + +int gt_ch_tx_reset(struct gt_ch *ch) +{ + if (!ch || !ch->ops || !ch->ops->tx_reset) + return -1; + + return ch->ops->tx_reset(ch); +} + +int gt_ch_get_rx_reset(struct gt_ch *ch, uint32_t *val) +{ + if (!ch || !ch->ops || !ch->ops->get_rx_reset) + return -1; + + return ch->ops->get_rx_reset(ch, val); +} + +int gt_ch_set_rx_reset(struct gt_ch *ch, uint32_t val) +{ + if (!ch || !ch->ops || !ch->ops->set_rx_reset) + return -1; + + return ch->ops->set_rx_reset(ch, val); +} + +int gt_ch_rx_reset(struct gt_ch *ch) +{ + if (!ch || !ch->ops || !ch->ops->rx_reset) + return -1; + + return ch->ops->rx_reset(ch); +} + +int gt_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val) +{ + if (!ch || !ch->ops || !ch->ops->get_tx_data_width) + return -1; + + return ch->ops->get_tx_data_width(ch, val); +} + +int gt_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + if (!ch || !ch->ops || !ch->ops->get_tx_int_data_width) + return -1; + + return ch->ops->get_tx_int_data_width(ch, val); +} + +int gt_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val) +{ + if (!ch || !ch->ops || !ch->ops->get_rx_data_width) + return -1; + + return ch->ops->get_rx_data_width(ch, val); +} + +int gt_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + if (!ch || !ch->ops || !ch->ops->get_rx_int_data_width) + return -1; + + return ch->ops->get_rx_int_data_width(ch, val); +} + +int gt_ch_get_available_presets(struct gt_ch *ch, const uint32_t **presets) +{ + if (!ch || !ch->ops || !ch->ops->get_available_presets) + return -1; + + return ch->ops->get_available_presets(ch, presets); +} + +int gt_ch_load_preset(struct gt_ch *ch, uint32_t preset) +{ + if (!ch || !ch->ops || !ch->ops->load_preset) + return -1; + + return ch->ops->load_preset(ch, preset); +} + +int gt_ch_eyescan_start(struct gt_ch *ch, struct gt_eyescan_params *params) +{ + if (!ch || !ch->ops || !ch->ops->eyescan_start) + return -1; + + return ch->ops->eyescan_start(ch, params); +} + +int gt_ch_eyescan_step(struct gt_ch *ch, struct gt_eyescan_point *point) +{ + if (!ch || !ch->ops || !ch->ops->eyescan_step) + return -1; + + return ch->ops->eyescan_step(ch, point); +} diff --git a/utils/xcvr_gt.h b/utils/xcvr_gt.h new file mode 100644 index 000000000..ce0d7ef8a --- /dev/null +++ b/utils/xcvr_gt.h @@ -0,0 +1,182 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#ifndef XCVR_GT_H +#define XCVR_GT_H + +#include +#include +#include "drp.h" + +struct gt_pll { + struct gt_quad *quad; +}; + +struct gt_ch { + struct gt_quad *quad; + struct gt_pll *pll; + const struct gt_ch_ops *ops; + void *priv; + + int index; +}; + +struct gt_quad { + struct mqnic_reg_if reg; + struct gt_pll pll; + struct gt_ch ch[4]; + const struct gt_quad_ops *ops; + void *priv; + const char *type; + + int index; + int ch_count; + int gt_type; +}; + +struct gt_reg_val { + uint16_t addr; + uint16_t mask; + uint16_t shift; + uint16_t value; +}; + +struct gt_eyescan_params { + uint64_t target_bit_count; + int h_range; + int h_start; + int h_stop; + int h_step; + int v_range; + int v_start; + int v_stop; + int v_step; +}; + +struct gt_eyescan_point { + uint64_t error_count; + uint64_t bit_count; + int x; + int y; + int ut_sign; +}; + +struct gt_quad_ops { + int (*init)(struct gt_quad *quad); +}; + +struct gt_ch_ops { + int (*get_tx_reset)(struct gt_ch *ch, uint32_t *val); + int (*set_tx_reset)(struct gt_ch *ch, uint32_t val); + int (*tx_reset)(struct gt_ch *ch); + int (*get_rx_reset)(struct gt_ch *ch, uint32_t *val); + int (*set_rx_reset)(struct gt_ch *ch, uint32_t val); + int (*rx_reset)(struct gt_ch *ch); + int (*get_tx_data_width)(struct gt_ch *ch, uint32_t *val); + int (*get_tx_int_data_width)(struct gt_ch *ch, uint32_t *val); + int (*get_rx_data_width)(struct gt_ch *ch, uint32_t *val); + int (*get_rx_int_data_width)(struct gt_ch *ch, uint32_t *val); + int (*get_available_presets)(struct gt_ch *ch, const uint32_t **presets); + int (*load_preset)(struct gt_ch *ch, uint32_t preset); + int (*eyescan_start)(struct gt_ch *ch, struct gt_eyescan_params *params); + int (*eyescan_step)(struct gt_ch *ch, struct gt_eyescan_point *point); +}; + +#define GT_PRESET_10G_DFE 0x0001010A +#define GT_PRESET_10G_LPM 0x0000010A +#define GT_PRESET_25G_DFE 0x0001190A +#define GT_PRESET_25G_LPM 0x0000190A + +int gt_pll_reg_read(struct gt_pll *pll, uint32_t addr, uint32_t *val); +int gt_pll_reg_read_masked(struct gt_pll *pll, uint32_t addr, uint32_t *val, uint32_t mask, uint32_t shift); +int gt_pll_reg_write(struct gt_pll *pll, uint32_t addr, uint32_t val); +int gt_pll_reg_write_masked(struct gt_pll *pll, uint32_t addr, uint32_t val, uint32_t mask, uint32_t shift); +int gt_pll_reg_write_multiple(struct gt_pll *pll, const struct gt_reg_val *vals); + +#define def_gt_pll_masked_reg_read16(prefix, name, addr, mask, shift) \ +static inline int prefix##_pll_get_##name(struct gt_pll *pll, uint32_t *val) \ +{ \ + return gt_pll_reg_read_masked(pll, addr, val, mask, shift); \ +} + +#define def_gt_pll_masked_reg_write16(prefix, name, addr, mask, shift) \ +static inline int prefix##_pll_set_##name(struct gt_pll *pll, uint32_t val) \ +{ \ + return gt_pll_reg_write_masked(pll, addr, val, mask, shift); \ +} + +#define def_gt_pll_masked_reg_rw16(prefix, name, addr, mask, shift) \ +def_gt_pll_masked_reg_read16(prefix, name, addr, mask, shift) \ +def_gt_pll_masked_reg_write16(prefix, name, addr, mask, shift) + +int gt_ch_reg_read(struct gt_ch *ch, uint32_t addr, uint32_t *val); +int gt_ch_reg_read_masked(struct gt_ch *ch, uint32_t addr, uint32_t *val, uint32_t mask, uint32_t shift); +int gt_ch_reg_write(struct gt_ch *ch, uint32_t addr, uint32_t val); +int gt_ch_reg_write_masked(struct gt_ch *ch, uint32_t addr, uint32_t val, uint32_t mask, uint32_t shift); +int gt_ch_reg_write_multiple(struct gt_ch *ch, const struct gt_reg_val *vals); + +#define def_gt_ch_masked_reg_read16(prefix, name, addr, mask, shift) \ +static inline int prefix##_ch_get_##name(struct gt_ch *ch, uint32_t *val) \ +{ \ + return gt_ch_reg_read_masked(ch, addr, val, mask, shift); \ +} + +#define def_gt_ch_masked_reg_write16(prefix, name, addr, mask, shift) \ +static inline int prefix##_ch_set_##name(struct gt_ch *ch, uint32_t val) \ +{ \ + return gt_ch_reg_write_masked(ch, addr, val, mask, shift); \ +} + +#define def_gt_ch_masked_reg_rw16(prefix, name, addr, mask, shift) \ +def_gt_ch_masked_reg_read16(prefix, name, addr, mask, shift) \ +def_gt_ch_masked_reg_write16(prefix, name, addr, mask, shift) + +struct gt_quad *gt_create_quad_from_drp_rb(struct mqnic_reg_block *rb); +void gt_free_quad(struct gt_quad *quad); + +int gt_ch_get_tx_reset(struct gt_ch *ch, uint32_t *val); +int gt_ch_set_tx_reset(struct gt_ch *ch, uint32_t val); +int gt_ch_tx_reset(struct gt_ch *ch); +int gt_ch_get_rx_reset(struct gt_ch *ch, uint32_t *val); +int gt_ch_set_rx_reset(struct gt_ch *ch, uint32_t val); +int gt_ch_rx_reset(struct gt_ch *ch); +int gt_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val); +int gt_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val); +int gt_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val); +int gt_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val); +int gt_ch_get_available_presets(struct gt_ch *ch, const uint32_t **presets); +int gt_ch_load_preset(struct gt_ch *ch, uint32_t preset); +int gt_ch_eyescan_start(struct gt_ch *ch, struct gt_eyescan_params *params); +int gt_ch_eyescan_step(struct gt_ch *ch, struct gt_eyescan_point *point); + +#endif /* XCVR_GT_H */ diff --git a/utils/xcvr_gthe3.c b/utils/xcvr_gthe3.c new file mode 100644 index 000000000..6fc300d41 --- /dev/null +++ b/utils/xcvr_gthe3.c @@ -0,0 +1,690 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include +#include +#include "xcvr_gthe3.h" + +// signals +int gthe3_pll_qpll0_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gthe3_pll_set_qpll0_reset(pll, 1); + + if (ret) + return ret; + + return gthe3_pll_set_qpll0_reset(pll, 0); +} + +int gthe3_pll_qpll1_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gthe3_pll_set_qpll1_reset(pll, 1); + + if (ret) + return ret; + + return gthe3_pll_set_qpll1_reset(pll, 0); +} + +int gthe3_ch_tx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_tx_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_tx_reset(ch, 0); +} + +int gthe3_ch_tx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_tx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_tx_pma_reset(ch, 0); +} + +int gthe3_ch_tx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_tx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_tx_pcs_reset(ch, 0); +} + +int gthe3_ch_rx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_rx_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_rx_reset(ch, 0); +} + +int gthe3_ch_rx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_rx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_rx_pma_reset(ch, 0); +} + +int gthe3_ch_rx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_rx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_rx_pcs_reset(ch, 0); +} + +int gthe3_ch_rx_dfe_lpm_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_rx_dfe_lpm_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_rx_dfe_lpm_reset(ch, 0); +} + +int gthe3_ch_eyescan_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe3_ch_set_eyescan_reset(ch, 1); + + if (ret) + return ret; + + return gthe3_ch_set_eyescan_reset(ch, 0); +} + +// RX +int gthe3_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gthe3_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gthe3_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gthe3_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gthe3_ch_get_rx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gthe3_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTHE3_CH_ES_QUAL_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gthe3_ch_set_es_qual_mask_clear(struct gt_ch *ch) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTHE3_CH_ES_QUAL_MASK0_ADDR+k, 0xffff); + if (ret) + return ret; + } + + return 0; +} + +int gthe3_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTHE3_CH_ES_SDATA_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gthe3_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + int shift = width - (40 - ((k+1)*16)); + uint32_t mask = 0xffff; + + if (shift < 0) + { + mask = 0xffff; + } + else if (shift > 16) + { + mask = 0x0000; + } + else + { + mask = 0xffff >> shift; + } + + ret = gt_ch_reg_write(ch, GTHE3_CH_ES_SDATA_MASK0_ADDR+k, mask); + if (ret) + return ret; + } + + return 0; +} + +int gthe3_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t v1, v2; + + ret = gt_ch_reg_read(ch, GTHE3_CH_RX_PRBS_ERR_CNT_L_ADDR | (ch->index << 17), &v1); + if (ret) + return ret; + + ret = gt_ch_reg_read(ch, GTHE3_CH_RX_PRBS_ERR_CNT_H_ADDR | (ch->index << 17), &v2); + if (ret) + return ret; + + *val = v1 | (v2 << 16); + return 0; +} + +// TX +int gthe3_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gthe3_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gthe3_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gthe3_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gthe3_ch_get_tx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +struct gthe3_ch_priv { + uint32_t tx_data_width; + uint32_t tx_int_data_width; + uint32_t rx_data_width; + uint32_t rx_int_data_width; + int dfe_en; + + int prescale; + int h_start; + int h_stop; + int h_step; + int v_range; + int v_start; + int v_stop; + int v_step; + + int h_offset; + int v_offset; + int ut_sign; + int eyescan_running; +}; + +static const struct gt_reg_val gthe3_ch_preset_10g_dfe_regs[] = { + {GTHE3_CH_CPLL_CFG2_ADDR, GTHE3_CH_CPLL_CFG2_MASK, GTHE3_CH_CPLL_CFG2_LSB, 0x5007}, + {GTHE3_CH_RXDFELPM_KL_CFG1_ADDR, GTHE3_CH_RXDFELPM_KL_CFG1_MASK, GTHE3_CH_RXDFELPM_KL_CFG1_LSB, 0x0002}, + {GTHE3_CH_RXPI_CFG0_ADDR, GTHE3_CH_RXPI_CFG0_MASK, GTHE3_CH_RXPI_CFG0_LSB, 0x0000}, + {GTHE3_CH_RXPI_CFG1_ADDR, GTHE3_CH_RXPI_CFG1_MASK, GTHE3_CH_RXPI_CFG1_LSB, 0x0000}, + {GTHE3_CH_RXPI_CFG2_ADDR, GTHE3_CH_RXPI_CFG2_MASK, GTHE3_CH_RXPI_CFG2_LSB, 0x0000}, + {GTHE3_CH_RXPI_CFG3_ADDR, GTHE3_CH_RXPI_CFG3_MASK, GTHE3_CH_RXPI_CFG3_LSB, 0x0000}, + {GTHE3_CH_RXPI_CFG6_ADDR, GTHE3_CH_RXPI_CFG6_MASK, GTHE3_CH_RXPI_CFG6_LSB, 0x0000}, + {GTHE3_CH_RX_DFE_AGC_CFG1_ADDR, GTHE3_CH_RX_DFE_AGC_CFG1_MASK, GTHE3_CH_RX_DFE_AGC_CFG1_LSB, 0x0004}, + {GTHE3_CH_RX_DFE_KL_LPM_KH_CFG1_ADDR, GTHE3_CH_RX_DFE_KL_LPM_KH_CFG1_MASK, GTHE3_CH_RX_DFE_KL_LPM_KH_CFG1_LSB, 0x0004}, + {GTHE3_CH_RX_DFE_KL_LPM_KL_CFG1_ADDR, GTHE3_CH_RX_DFE_KL_LPM_KL_CFG1_MASK, GTHE3_CH_RX_DFE_KL_LPM_KL_CFG1_LSB, 0x0004}, + {GTHE3_CH_RX_SUM_IREF_TUNE_ADDR, GTHE3_CH_RX_SUM_IREF_TUNE_MASK, GTHE3_CH_RX_SUM_IREF_TUNE_LSB, 0x0000}, + {GTHE3_CH_RX_SUM_RES_CTRL_ADDR, GTHE3_CH_RX_SUM_RES_CTRL_MASK, GTHE3_CH_RX_SUM_RES_CTRL_LSB, 0x0000}, + {GTHE3_CH_TXPI_CFG0_ADDR, GTHE3_CH_TXPI_CFG0_MASK, GTHE3_CH_TXPI_CFG0_LSB, 0x0000}, + {GTHE3_CH_TXPI_CFG1_ADDR, GTHE3_CH_TXPI_CFG1_MASK, GTHE3_CH_TXPI_CFG1_LSB, 0x0000}, + {GTHE3_CH_TXPI_CFG2_ADDR, GTHE3_CH_TXPI_CFG2_MASK, GTHE3_CH_TXPI_CFG2_LSB, 0x0000}, + {GTHE3_CH_TXPI_CFG3_ADDR, GTHE3_CH_TXPI_CFG3_MASK, GTHE3_CH_TXPI_CFG3_LSB, 0x0001}, + {GTHE3_CH_TXPI_CFG5_ADDR, GTHE3_CH_TXPI_CFG5_MASK, GTHE3_CH_TXPI_CFG5_LSB, 0x0000}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gthe3_ch_preset_10g_lpm_regs[] = { + {GTHE3_CH_CPLL_CFG2_ADDR, GTHE3_CH_CPLL_CFG2_MASK, GTHE3_CH_CPLL_CFG2_LSB, 0x0007}, + {GTHE3_CH_RXDFELPM_KL_CFG1_ADDR, GTHE3_CH_RXDFELPM_KL_CFG1_MASK, GTHE3_CH_RXDFELPM_KL_CFG1_LSB, 0x0032}, + {GTHE3_CH_RXPI_CFG0_ADDR, GTHE3_CH_RXPI_CFG0_MASK, GTHE3_CH_RXPI_CFG0_LSB, 0x0001}, + {GTHE3_CH_RXPI_CFG1_ADDR, GTHE3_CH_RXPI_CFG1_MASK, GTHE3_CH_RXPI_CFG1_LSB, 0x0001}, + {GTHE3_CH_RXPI_CFG2_ADDR, GTHE3_CH_RXPI_CFG2_MASK, GTHE3_CH_RXPI_CFG2_LSB, 0x0001}, + {GTHE3_CH_RXPI_CFG3_ADDR, GTHE3_CH_RXPI_CFG3_MASK, GTHE3_CH_RXPI_CFG3_LSB, 0x0001}, + {GTHE3_CH_RXPI_CFG6_ADDR, GTHE3_CH_RXPI_CFG6_MASK, GTHE3_CH_RXPI_CFG6_LSB, 0x0003}, + {GTHE3_CH_RX_DFE_AGC_CFG1_ADDR, GTHE3_CH_RX_DFE_AGC_CFG1_MASK, GTHE3_CH_RX_DFE_AGC_CFG1_LSB, 0x0000}, + {GTHE3_CH_RX_DFE_KL_LPM_KH_CFG1_ADDR, GTHE3_CH_RX_DFE_KL_LPM_KH_CFG1_MASK, GTHE3_CH_RX_DFE_KL_LPM_KH_CFG1_LSB, 0x0000}, + {GTHE3_CH_RX_DFE_KL_LPM_KL_CFG1_ADDR, GTHE3_CH_RX_DFE_KL_LPM_KL_CFG1_MASK, GTHE3_CH_RX_DFE_KL_LPM_KL_CFG1_LSB, 0x0000}, + {GTHE3_CH_RX_SUM_IREF_TUNE_ADDR, GTHE3_CH_RX_SUM_IREF_TUNE_MASK, GTHE3_CH_RX_SUM_IREF_TUNE_LSB, 0x000C}, + {GTHE3_CH_RX_SUM_RES_CTRL_ADDR, GTHE3_CH_RX_SUM_RES_CTRL_MASK, GTHE3_CH_RX_SUM_RES_CTRL_LSB, 0x0003}, + {GTHE3_CH_TXPI_CFG0_ADDR, GTHE3_CH_TXPI_CFG0_MASK, GTHE3_CH_TXPI_CFG0_LSB, 0x0001}, + {GTHE3_CH_TXPI_CFG1_ADDR, GTHE3_CH_TXPI_CFG1_MASK, GTHE3_CH_TXPI_CFG1_LSB, 0x0001}, + {GTHE3_CH_TXPI_CFG2_ADDR, GTHE3_CH_TXPI_CFG2_MASK, GTHE3_CH_TXPI_CFG2_LSB, 0x0001}, + {GTHE3_CH_TXPI_CFG3_ADDR, GTHE3_CH_TXPI_CFG3_MASK, GTHE3_CH_TXPI_CFG3_LSB, 0x0000}, + {GTHE3_CH_TXPI_CFG5_ADDR, GTHE3_CH_TXPI_CFG5_MASK, GTHE3_CH_TXPI_CFG5_LSB, 0x0003}, + {0, 0, 0, 0} +}; + +static const uint32_t gthe3_ch_presets[] = { + GT_PRESET_10G_DFE, + GT_PRESET_10G_LPM, + 0 +}; + +static int gthe3_ch_get_available_presets(struct gt_ch *ch, const uint32_t **presets) +{ + *presets = gthe3_ch_presets; + return 0; +} + +int gthe3_ch_load_preset(struct gt_ch *ch, uint32_t preset) +{ + if (preset == GT_PRESET_10G_DFE || preset == GT_PRESET_10G_LPM) + { + gthe3_ch_set_tx_reset(ch, 1); + gthe3_ch_set_rx_reset(ch, 1); + + if (preset == GT_PRESET_10G_DFE) + { + gt_ch_reg_write_multiple(ch, gthe3_ch_preset_10g_dfe_regs); + gthe3_ch_set_rx_lpm_en(ch, 0); + } + else + { + gt_ch_reg_write_multiple(ch, gthe3_ch_preset_10g_lpm_regs); + gthe3_ch_set_rx_lpm_en(ch, 1); + } + + gthe3_ch_set_tx_reset(ch, 0); + gthe3_ch_set_rx_reset(ch, 0); + + return 0; + } + + return -1; +} + +static int gthe3_ch_eyescan_start(struct gt_ch *ch, struct gt_eyescan_params *params) +{ + struct gthe3_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + float ber; + + priv->eyescan_running = 0; + + gthe3_ch_get_rx_lpm_en(ch, &val); + priv->dfe_en = !val; + + gthe3_ch_get_rx_data_width(ch, &priv->rx_data_width); + gthe3_ch_get_rx_int_data_width(ch, &priv->rx_int_data_width); + + priv->prescale = 0; + + for (priv->prescale = 0; priv->prescale < 32; priv->prescale++) + { + if (((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale) >= params->target_bit_count) + break; + } + + params->target_bit_count = ((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + params->h_range = 0; + + priv->h_start = params->h_start; + priv->h_stop = params->h_stop; + priv->h_step = params->h_step; + priv->v_range = params->v_range; + priv->v_start = params->v_start; + priv->v_stop = params->v_stop; + priv->v_step = params->v_step; + + gthe3_ch_set_es_control(ch, 0x00); + + gthe3_ch_set_es_prescale(ch, 4); + gthe3_ch_set_es_errdet_en(ch, 1); + + gthe3_ch_set_es_qual_mask_clear(ch); + gthe3_ch_set_es_sdata_mask_width(ch, priv->rx_int_data_width); + + gthe3_ch_set_rx_eyescan_vs_range(ch, priv->v_range); + + gthe3_ch_set_es_horz_offset(ch, 0x000); + gthe3_ch_set_rx_eyescan_vs_neg_dir(ch, 0); + gthe3_ch_set_rx_eyescan_vs_code(ch, 0); + gthe3_ch_set_rx_eyescan_vs_ut_sign(ch, 0); + + gthe3_ch_set_es_eye_scan_en(ch, 1); + + gthe3_ch_rx_pma_reset(ch); + + for (int ber_tries = 0; ber_tries < 10; ber_tries++) + { + for (int reset_tries = 0; reset_tries < 30; reset_tries++) + { + gthe3_ch_get_rx_reset_done(ch, &val); + if (val) + break; + usleep(100000); + } + + if (!val) + { + fprintf(stderr, "Error: channel stuck in reset\n"); + return -1; + } + + usleep(100000); + + // check for lock + gthe3_ch_set_es_control(ch, 0x01); + + for (int wait_tries = 0; wait_tries < 30; wait_tries++) + { + gthe3_ch_get_es_control_status(ch, &val); + if (val & 1) + break; + usleep(100000); + } + + if (!(val & 1)) + { + fprintf(stderr, "Error: eye scan did not finish (%d)\n", val); + return -1; + } + + gthe3_ch_set_es_control(ch, 0x00); + + gthe3_ch_get_es_error_count(ch, &error_count); + gthe3_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+4); + + ber = (float)error_count / (float)bit_count; + + if (ber < 0.01) + break; + + printf("High BER (%02f), resetting eye scan logic\n", ber); + + gthe3_ch_set_es_horz_offset(ch, 0x880); + gthe3_ch_set_eyescan_reset(ch, 1); + gthe3_ch_set_es_horz_offset(ch, 0x800); + gthe3_ch_set_eyescan_reset(ch, 0); + } + + if (ber > 0.01) + { + fprintf(stderr, "Error: High BER, alignment failed\n"); + return -1; + } + + // set up for measurement + priv->h_offset = priv->h_start; + priv->v_offset = priv->v_start; + priv->ut_sign = 0; + + gthe3_ch_set_es_control(ch, 0x00); + gthe3_ch_set_es_prescale(ch, priv->prescale); + gthe3_ch_set_es_errdet_en(ch, 1); + gthe3_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | (priv->h_offset < 0 ? 0x800 : 0x000)); + gthe3_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gthe3_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + gthe3_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + // start measurement + gthe3_ch_set_es_control(ch, 0x01); + + priv->eyescan_running = 1; + + return 0; +} + +static int gthe3_ch_eyescan_step(struct gt_ch *ch, struct gt_eyescan_point *point) +{ + struct gthe3_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + + int restart = 0; + + if (!priv->eyescan_running) + return 0; + + gthe3_ch_get_es_control_status(ch, &val); + if (!(val & 1)) + return 2; + + gthe3_ch_set_es_control(ch, 0x00); + + gthe3_ch_get_es_error_count(ch, &error_count); + gthe3_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + + point->error_count = error_count; + point->bit_count = bit_count; + point->x = priv->h_offset; + point->y = priv->v_offset; + point->ut_sign = priv->ut_sign; + + restart = 0; + + if (!priv->ut_sign && priv->dfe_en) + { + priv->ut_sign = 1; + restart = 1; + } + else + { + priv->ut_sign = 0; + } + + gthe3_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + if (restart) + { + gthe3_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->v_offset < priv->v_stop) + { + priv->v_offset += priv->v_step; + restart = 1; + } + else + { + priv->v_offset = priv->v_start; + } + + gthe3_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gthe3_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + + if (restart) + { + gthe3_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->h_offset < priv->h_stop) + { + priv->h_offset += priv->h_step; + restart = 1; + } + else + { + // done + priv->eyescan_running = 0; + return 1; + } + + gthe3_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | (priv->h_offset < 0 ? 0x800 : 0x000)); + + if (restart) + { + gthe3_ch_set_es_control(ch, 0x01); + return 1; + } + + priv->eyescan_running = 0; + return 0; +} + +const struct gt_ch_ops gthe3_gt_ch_ops = { + .get_tx_reset = gthe3_ch_get_tx_reset, + .set_tx_reset = gthe3_ch_set_tx_reset, + .tx_reset = gthe3_ch_tx_reset, + .get_rx_reset = gthe3_ch_get_rx_reset, + .set_rx_reset = gthe3_ch_set_rx_reset, + .rx_reset = gthe3_ch_rx_reset, + .get_tx_data_width = gthe3_ch_get_tx_data_width, + .get_tx_int_data_width = gthe3_ch_get_tx_int_data_width, + .get_rx_data_width = gthe3_ch_get_rx_data_width, + .get_rx_int_data_width = gthe3_ch_get_rx_int_data_width, + .get_available_presets = gthe3_ch_get_available_presets, + .load_preset = gthe3_ch_load_preset, + .eyescan_start = gthe3_ch_eyescan_start, + .eyescan_step = gthe3_ch_eyescan_step +}; + +static int gthe3_ch_init(struct gt_ch *ch) +{ + struct gthe3_ch_priv *priv = calloc(1, sizeof(struct gthe3_ch_priv)); + if (!priv) + return -1; + + ch->priv = priv; + + return 0; +} + +int gthe3_quad_init(struct gt_quad *quad) +{ + quad->type = "GTHE3"; + + for (int n = 0; n < quad->ch_count; n++) + { + quad->ch[n].quad = quad; + quad->ch[n].pll = &quad->pll; + quad->ch[n].ops = >he3_gt_ch_ops; + quad->ch[n].index = n; + + gthe3_ch_init(&quad->ch[n]); + } + + return 0; +} + +const struct gt_quad_ops gthe3_gt_quad_ops = { + .init = gthe3_quad_init +}; diff --git a/utils/xcvr_gthe3.h b/utils/xcvr_gthe3.h new file mode 100644 index 000000000..85f35e79d --- /dev/null +++ b/utils/xcvr_gthe3.h @@ -0,0 +1,403 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#ifndef XCVR_GTHE3_H +#define XCVR_GTHE3_H + +#include "xcvr_gt.h" +#include "gt/gthe3_regs.h" + +// signals +#define GTHE3_COM_QPLL0_RESET_ADDR 0x10000 +#define GTHE3_COM_QPLL0_RESET_MSB 0 +#define GTHE3_COM_QPLL0_RESET_LSB 0 +#define GTHE3_COM_QPLL0_RESET_MASK BIT_MASK(GTHE3_COM_QPLL0_RESET_MSB, GTHE3_COM_QPLL0_RESET_LSB) +#define GTHE3_COM_QPLL0_LOCK_ADDR 0x10000 +#define GTHE3_COM_QPLL0_LOCK_MSB 8 +#define GTHE3_COM_QPLL0_LOCK_LSB 8 +#define GTHE3_COM_QPLL0_LOCK_MASK BIT_MASK(GTHE3_COM_QPLL0_LOCK_MSB, GTHE3_COM_QPLL0_LOCK_LSB) +#define GTHE3_COM_QPLL0_PD_ADDR 0x10001 +#define GTHE3_COM_QPLL0_PD_MSB 0 +#define GTHE3_COM_QPLL0_PD_LSB 0 +#define GTHE3_COM_QPLL0_PD_MASK BIT_MASK(GTHE3_COM_QPLL0_PD_MSB, GTHE3_COM_QPLL0_PD_LSB) +#define GTHE3_COM_QPLL1_RESET_ADDR 0x11000 +#define GTHE3_COM_QPLL1_RESET_MSB 0 +#define GTHE3_COM_QPLL1_RESET_LSB 0 +#define GTHE3_COM_QPLL1_RESET_MASK BIT_MASK(GTHE3_COM_QPLL0_RESET_MSB, GTHE3_COM_QPLL0_RESET_LSB) +#define GTHE3_COM_QPLL1_LOCK_ADDR 0x11000 +#define GTHE3_COM_QPLL1_LOCK_MSB 8 +#define GTHE3_COM_QPLL1_LOCK_LSB 8 +#define GTHE3_COM_QPLL1_LOCK_MASK BIT_MASK(GTHE3_COM_QPLL0_LOCK_MSB, GTHE3_COM_QPLL0_LOCK_LSB) +#define GTHE3_COM_QPLL1_PD_ADDR 0x11001 +#define GTHE3_COM_QPLL1_PD_MSB 0 +#define GTHE3_COM_QPLL1_PD_LSB 0 +#define GTHE3_COM_QPLL1_PD_MASK BIT_MASK(GTHE3_COM_QPLL1_PD_MSB, GTHE3_COM_QPLL1_PD_LSB) + +#define GTHE3_CH_TX_RESET_ADDR 0x10000 +#define GTHE3_CH_TX_RESET_MSB 0 +#define GTHE3_CH_TX_RESET_LSB 0 +#define GTHE3_CH_TX_RESET_MASK BIT_MASK(GTHE3_CH_TX_RESET_MSB, GTHE3_CH_TX_RESET_LSB) +#define GTHE3_CH_TX_PMA_RESET_ADDR 0x10000 +#define GTHE3_CH_TX_PMA_RESET_MSB 1 +#define GTHE3_CH_TX_PMA_RESET_LSB 1 +#define GTHE3_CH_TX_PMA_RESET_MASK BIT_MASK(GTHE3_CH_TX_PMA_RESET_MSB, GTHE3_CH_TX_PMA_RESET_LSB) +#define GTHE3_CH_TX_PCS_RESET_ADDR 0x10000 +#define GTHE3_CH_TX_PCS_RESET_MSB 2 +#define GTHE3_CH_TX_PCS_RESET_LSB 2 +#define GTHE3_CH_TX_PCS_RESET_MASK BIT_MASK(GTHE3_CH_TX_PCS_RESET_MSB, GTHE3_CH_TX_PCS_RESET_LSB) +#define GTHE3_CH_TX_RESET_DONE_ADDR 0x10000 +#define GTHE3_CH_TX_RESET_DONE_MSB 8 +#define GTHE3_CH_TX_RESET_DONE_LSB 8 +#define GTHE3_CH_TX_RESET_DONE_MASK BIT_MASK(GTHE3_CH_TX_RESET_DONE_MSB, GTHE3_CH_TX_RESET_DONE_LSB) +#define GTHE3_CH_TX_GT_RESET_DONE_ADDR 0x10000 +#define GTHE3_CH_TX_GT_RESET_DONE_MSB 9 +#define GTHE3_CH_TX_GT_RESET_DONE_LSB 9 +#define GTHE3_CH_TX_GT_RESET_DONE_MASK BIT_MASK(GTHE3_CH_TX_GT_RESET_DONE_MSB, GTHE3_CH_TX_GT_RESET_DONE_LSB) +#define GTHE3_CH_TX_PMA_RESET_DONE_ADDR 0x10000 +#define GTHE3_CH_TX_PMA_RESET_DONE_MSB 10 +#define GTHE3_CH_TX_PMA_RESET_DONE_LSB 10 +#define GTHE3_CH_TX_PMA_RESET_DONE_MASK BIT_MASK(GTHE3_CH_TX_PMA_RESET_DONE_MSB, GTHE3_CH_TX_PMA_RESET_DONE_LSB) +#define GTHE3_CH_TX_PRGDIV_RESET_DONE_ADDR 0x10000 +#define GTHE3_CH_TX_PRGDIV_RESET_DONE_MSB 11 +#define GTHE3_CH_TX_PRGDIV_RESET_DONE_LSB 11 +#define GTHE3_CH_TX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTHE3_CH_TX_PRGDIV_RESET_DONE_MSB, GTHE3_CH_TX_PRGDIV_RESET_DONE_LSB) +#define GTHE3_CH_TX_USRCLK_ACT_ADDR 0x10000 +#define GTHE3_CH_TX_USRCLK_ACT_MSB 12 +#define GTHE3_CH_TX_USRCLK_ACT_LSB 12 +#define GTHE3_CH_TX_USRCLK_ACT_MASK BIT_MASK(GTHE3_CH_TX_USRCLK_ACT_MSB, GTHE3_CH_TX_USRCLK_ACT_LSB) +#define GTHE3_CH_TX_PD_ADDR 0x10001 +#define GTHE3_CH_TX_PD_MSB 0 +#define GTHE3_CH_TX_PD_LSB 0 +#define GTHE3_CH_TX_PD_MASK BIT_MASK(GTHE3_CH_TX_PD_MSB, GTHE3_CH_TX_PD_LSB) +#define GTHE3_CH_TX_QPLL_SEL_ADDR 0x10001 +#define GTHE3_CH_TX_QPLL_SEL_MSB 1 +#define GTHE3_CH_TX_QPLL_SEL_LSB 1 +#define GTHE3_CH_TX_QPLL_SEL_MASK BIT_MASK(GTHE3_CH_TX_QPLL_SEL_MSB, GTHE3_CH_TX_QPLL_SEL_LSB) +#define GTHE3_CH_TX_POLARITY_ADDR 0x10010 +#define GTHE3_CH_TX_POLARITY_MSB 0 +#define GTHE3_CH_TX_POLARITY_LSB 0 +#define GTHE3_CH_TX_POLARITY_MASK BIT_MASK(GTHE3_CH_TX_POLARITY_MSB, GTHE3_CH_TX_POLARITY_LSB) +#define GTHE3_CH_TX_ELECIDLE_ADDR 0x10010 +#define GTHE3_CH_TX_ELECIDLE_MSB 1 +#define GTHE3_CH_TX_ELECIDLE_LSB 1 +#define GTHE3_CH_TX_ELECIDLE_MASK BIT_MASK(GTHE3_CH_TX_ELECIDLE_MSB, GTHE3_CH_TX_ELECIDLE_LSB) +#define GTHE3_CH_TX_INHIBIT_ADDR 0x10010 +#define GTHE3_CH_TX_INHIBIT_MSB 2 +#define GTHE3_CH_TX_INHIBIT_LSB 2 +#define GTHE3_CH_TX_INHIBIT_MASK BIT_MASK(GTHE3_CH_TX_INHIBIT_MSB, GTHE3_CH_TX_INHIBIT_LSB) +#define GTHE3_CH_TX_DIFFCTRL_ADDR 0x10011 +#define GTHE3_CH_TX_DIFFCTRL_MSB 4 +#define GTHE3_CH_TX_DIFFCTRL_LSB 0 +#define GTHE3_CH_TX_DIFFCTRL_MASK BIT_MASK(GTHE3_CH_TX_DIFFCTRL_MSB, GTHE3_CH_TX_DIFFCTRL_LSB) +#define GTHE3_CH_TX_MAINCURSOR_ADDR 0x10012 +#define GTHE3_CH_TX_MAINCURSOR_MSB 6 +#define GTHE3_CH_TX_MAINCURSOR_LSB 0 +#define GTHE3_CH_TX_MAINCURSOR_MASK BIT_MASK(GTHE3_CH_TX_MAINCURSOR_MSB, GTHE3_CH_TX_MAINCURSOR_LSB) +#define GTHE3_CH_TX_PRECURSOR_ADDR 0x10013 +#define GTHE3_CH_TX_PRECURSOR_MSB 4 +#define GTHE3_CH_TX_PRECURSOR_LSB 0 +#define GTHE3_CH_TX_PRECURSOR_MASK BIT_MASK(GTHE3_CH_TX_PRECURSOR_MSB, GTHE3_CH_TX_PRECURSOR_LSB) +#define GTHE3_CH_TX_POSTCURSOR_ADDR 0x10014 +#define GTHE3_CH_TX_POSTCURSOR_MSB 4 +#define GTHE3_CH_TX_POSTCURSOR_LSB 0 +#define GTHE3_CH_TX_POSTCURSOR_MASK BIT_MASK(GTHE3_CH_TX_POSTCURSOR_MSB, GTHE3_CH_TX_POSTCURSOR_LSB) +#define GTHE3_CH_TX_PRBS_SEL_ADDR 0x10040 +#define GTHE3_CH_TX_PRBS_SEL_MSB 3 +#define GTHE3_CH_TX_PRBS_SEL_LSB 0 +#define GTHE3_CH_TX_PRBS_SEL_MASK BIT_MASK(GTHE3_CH_TX_PRBS_SEL_MSB, GTHE3_CH_TX_PRBS_SEL_LSB) +#define GTHE3_CH_TX_PRBS_FORCERR_ADDR 0x10040 +#define GTHE3_CH_TX_PRBS_FORCERR_MSB 15 +#define GTHE3_CH_TX_PRBS_FORCERR_LSB 0 +#define GTHE3_CH_TX_PRBS_FORCERR_MASK BIT_MASK(GTHE3_CH_TX_PRBS_FORCERR_MSB, GTHE3_CH_TX_PRBS_FORCERR_LSB) +#define GTHE3_CH_RX_RESET_ADDR 0x11000 +#define GTHE3_CH_RX_RESET_MSB 0 +#define GTHE3_CH_RX_RESET_LSB 0 +#define GTHE3_CH_RX_RESET_MASK BIT_MASK(GTHE3_CH_RX_RESET_MSB, GTHE3_CH_RX_RESET_LSB) +#define GTHE3_CH_RX_PMA_RESET_ADDR 0x11000 +#define GTHE3_CH_RX_PMA_RESET_MSB 1 +#define GTHE3_CH_RX_PMA_RESET_LSB 1 +#define GTHE3_CH_RX_PMA_RESET_MASK BIT_MASK(GTHE3_CH_RX_PMA_RESET_MSB, GTHE3_CH_RX_PMA_RESET_LSB) +#define GTHE3_CH_RX_PCS_RESET_ADDR 0x11000 +#define GTHE3_CH_RX_PCS_RESET_MSB 2 +#define GTHE3_CH_RX_PCS_RESET_LSB 2 +#define GTHE3_CH_RX_PCS_RESET_MASK BIT_MASK(GTHE3_CH_RX_PCS_RESET_MSB, GTHE3_CH_RX_PCS_RESET_LSB) +#define GTHE3_CH_RX_DFE_LPM_RESET_ADDR 0x11000 +#define GTHE3_CH_RX_DFE_LPM_RESET_MSB 3 +#define GTHE3_CH_RX_DFE_LPM_RESET_LSB 3 +#define GTHE3_CH_RX_DFE_LPM_RESET_MASK BIT_MASK(GTHE3_CH_RX_DFE_LPM_RESET_MSB, GTHE3_CH_RX_DFE_LPM_RESET_LSB) +#define GTHE3_CH_EYESCAN_RESET_ADDR 0x11000 +#define GTHE3_CH_EYESCAN_RESET_MSB 4 +#define GTHE3_CH_EYESCAN_RESET_LSB 4 +#define GTHE3_CH_EYESCAN_RESET_MASK BIT_MASK(GTHE3_CH_EYESCAN_RESET_MSB, GTHE3_CH_EYESCAN_RESET_LSB) +#define GTHE3_CH_RX_RESET_DONE_ADDR 0x11000 +#define GTHE3_CH_RX_RESET_DONE_MSB 8 +#define GTHE3_CH_RX_RESET_DONE_LSB 8 +#define GTHE3_CH_RX_RESET_DONE_MASK BIT_MASK(GTHE3_CH_RX_RESET_DONE_MSB, GTHE3_CH_RX_RESET_DONE_LSB) +#define GTHE3_CH_RX_GT_RESET_DONE_ADDR 0x11000 +#define GTHE3_CH_RX_GT_RESET_DONE_MSB 9 +#define GTHE3_CH_RX_GT_RESET_DONE_LSB 9 +#define GTHE3_CH_RX_GT_RESET_DONE_MASK BIT_MASK(GTHE3_CH_RX_GT_RESET_DONE_MSB, GTHE3_CH_RX_GT_RESET_DONE_LSB) +#define GTHE3_CH_RX_PMA_RESET_DONE_ADDR 0x11000 +#define GTHE3_CH_RX_PMA_RESET_DONE_MSB 10 +#define GTHE3_CH_RX_PMA_RESET_DONE_LSB 10 +#define GTHE3_CH_RX_PMA_RESET_DONE_MASK BIT_MASK(GTHE3_CH_RX_PMA_RESET_DONE_MSB, GTHE3_CH_RX_PMA_RESET_DONE_LSB) +#define GTHE3_CH_RX_PRGDIV_RESET_DONE_ADDR 0x11000 +#define GTHE3_CH_RX_PRGDIV_RESET_DONE_MSB 11 +#define GTHE3_CH_RX_PRGDIV_RESET_DONE_LSB 11 +#define GTHE3_CH_RX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTHE3_CH_RX_PRGDIV_RESET_DONE_MSB, GTHE3_CH_RX_PRGDIV_RESET_DONE_LSB) +#define GTHE3_CH_RX_USRCLK_ACT_ADDR 0x11000 +#define GTHE3_CH_RX_USRCLK_ACT_MSB 12 +#define GTHE3_CH_RX_USRCLK_ACT_LSB 12 +#define GTHE3_CH_RX_USRCLK_ACT_MASK BIT_MASK(GTHE3_CH_RX_USRCLK_ACT_MSB, GTHE3_CH_RX_USRCLK_ACT_LSB) +#define GTHE3_CH_RX_PD_ADDR 0x11001 +#define GTHE3_CH_RX_PD_MSB 0 +#define GTHE3_CH_RX_PD_LSB 0 +#define GTHE3_CH_RX_PD_MASK BIT_MASK(GTHE3_CH_RX_PD_MSB, GTHE3_CH_RX_PD_LSB) +#define GTHE3_CH_RX_QPLL_SEL_ADDR 0x11001 +#define GTHE3_CH_RX_QPLL_SEL_MSB 1 +#define GTHE3_CH_RX_QPLL_SEL_LSB 1 +#define GTHE3_CH_RX_QPLL_SEL_MASK BIT_MASK(GTHE3_CH_RX_QPLL_SEL_MSB, GTHE3_CH_RX_QPLL_SEL_LSB) +#define GTHE3_CH_LOOPBACK_ADDR 0x11002 +#define GTHE3_CH_LOOPBACK_MSB 2 +#define GTHE3_CH_LOOPBACK_LSB 0 +#define GTHE3_CH_LOOPBACK_MASK BIT_MASK(GTHE3_CH_LOOPBACK_MSB, GTHE3_CH_LOOPBACK_LSB) +#define GTHE3_CH_RX_POLARITY_ADDR 0x11010 +#define GTHE3_CH_RX_POLARITY_MSB 0 +#define GTHE3_CH_RX_POLARITY_LSB 0 +#define GTHE3_CH_RX_POLARITY_MASK BIT_MASK(GTHE3_CH_RX_POLARITY_MSB, GTHE3_CH_RX_POLARITY_LSB) +#define GTHE3_CH_RX_CDR_HOLD_ADDR 0x11020 +#define GTHE3_CH_RX_CDR_HOLD_MSB 0 +#define GTHE3_CH_RX_CDR_HOLD_LSB 0 +#define GTHE3_CH_RX_CDR_HOLD_MASK BIT_MASK(GTHE3_CH_RX_CDR_HOLD_MSB, GTHE3_CH_RX_CDR_HOLD_LSB) +#define GTHE3_CH_RX_CDR_LOCK_ADDR 0x11020 +#define GTHE3_CH_RX_CDR_LOCK_MSB 8 +#define GTHE3_CH_RX_CDR_LOCK_LSB 8 +#define GTHE3_CH_RX_CDR_LOCK_MASK BIT_MASK(GTHE3_CH_RX_CDR_LOCK_MSB, GTHE3_CH_RX_CDR_LOCK_LSB) +#define GTHE3_CH_RX_LPM_EN_ADDR 0x11024 +#define GTHE3_CH_RX_LPM_EN_MSB 0 +#define GTHE3_CH_RX_LPM_EN_LSB 0 +#define GTHE3_CH_RX_LPM_EN_MASK BIT_MASK(GTHE3_CH_RX_LPM_EN_MSB, GTHE3_CH_RX_LPM_EN_LSB) +#define GTHE3_CH_RX_DMONITOR_ADDR 0x11028 +#define GTHE3_CH_RX_DMONITOR_MSB 7 +#define GTHE3_CH_RX_DMONITOR_LSB 0 +#define GTHE3_CH_RX_DMONITOR_MASK BIT_MASK(GTHE3_CH_RX_DMONITOR_MSB, GTHE3_CH_RX_DMONITOR_LSB) +#define GTHE3_CH_RX_PRBS_SEL_ADDR 0x11040 +#define GTHE3_CH_RX_PRBS_SEL_MSB 3 +#define GTHE3_CH_RX_PRBS_SEL_LSB 0 +#define GTHE3_CH_RX_PRBS_SEL_MASK BIT_MASK(GTHE3_CH_RX_PRBS_SEL_MSB, GTHE3_CH_RX_PRBS_SEL_LSB) +#define GTHE3_CH_RX_PRBS_CNT_RESET_ADDR 0x11041 +#define GTHE3_CH_RX_PRBS_CNT_RESET_MSB 0 +#define GTHE3_CH_RX_PRBS_CNT_RESET_LSB 0 +#define GTHE3_CH_RX_PRBS_CNT_RESET_MASK BIT_MASK(GTHE3_CH_RX_PRBS_CNT_RESET_MSB, GTHE3_CH_RX_PRBS_CNT_RESET_LSB) +#define GTHE3_CH_RX_PRBS_LOCKED_ADDR 0x11041 +#define GTHE3_CH_RX_PRBS_LOCKED_MSB 8 +#define GTHE3_CH_RX_PRBS_LOCKED_LSB 8 +#define GTHE3_CH_RX_PRBS_LOCKED_MASK BIT_MASK(GTHE3_CH_RX_PRBS_LOCKED_MSB, GTHE3_CH_RX_PRBS_LOCKED_LSB) +#define GTHE3_CH_RX_PRBS_ERROR_ADDR 0x11041 +#define GTHE3_CH_RX_PRBS_ERROR_MSB 9 +#define GTHE3_CH_RX_PRBS_ERROR_LSB 9 +#define GTHE3_CH_RX_PRBS_ERROR_MASK BIT_MASK(GTHE3_CH_RX_PRBS_ERROR_MSB, GTHE3_CH_RX_PRBS_ERROR_LSB) + + +def_gt_pll_masked_reg_rw16(gthe3, qpll0_reset, GTHE3_COM_QPLL0_RESET_ADDR, GTHE3_COM_QPLL0_RESET_MASK, GTHE3_COM_QPLL0_RESET_LSB); +int gthe3_pll_qpll0_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gthe3, qpll0_lock, GTHE3_COM_QPLL0_LOCK_ADDR, GTHE3_COM_QPLL0_LOCK_MASK, GTHE3_COM_QPLL0_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_pd, GTHE3_COM_QPLL0_PD_ADDR, GTHE3_COM_QPLL0_PD_MASK, GTHE3_COM_QPLL0_PD_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_reset, GTHE3_COM_QPLL1_RESET_ADDR, GTHE3_COM_QPLL1_RESET_MASK, GTHE3_COM_QPLL1_RESET_LSB); +int gthe3_pll_qpll1_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gthe3, qpll1_lock, GTHE3_COM_QPLL1_LOCK_ADDR, GTHE3_COM_QPLL1_LOCK_MASK, GTHE3_COM_QPLL1_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_pd, GTHE3_COM_QPLL1_PD_ADDR, GTHE3_COM_QPLL1_PD_MASK, GTHE3_COM_QPLL1_PD_LSB); + +def_gt_ch_masked_reg_rw16(gthe3, tx_reset, GTHE3_CH_TX_RESET_ADDR, GTHE3_CH_TX_RESET_MASK, GTHE3_CH_TX_RESET_LSB); +int gthe3_ch_tx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe3, tx_pma_reset, GTHE3_CH_TX_PMA_RESET_ADDR, GTHE3_CH_TX_PMA_RESET_MASK, GTHE3_CH_TX_PMA_RESET_LSB); +int gthe3_ch_tx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe3, tx_pcs_reset, GTHE3_CH_TX_PCS_RESET_ADDR, GTHE3_CH_TX_PCS_RESET_MASK, GTHE3_CH_TX_PCS_RESET_LSB); +int gthe3_ch_tx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gthe3, tx_reset_done, GTHE3_CH_TX_RESET_DONE_ADDR, GTHE3_CH_TX_RESET_DONE_MASK, GTHE3_CH_TX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, tx_gt_reset_done, GTHE3_CH_TX_GT_RESET_DONE_ADDR, GTHE3_CH_TX_GT_RESET_DONE_MASK, GTHE3_CH_TX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, tx_pma_reset_done, GTHE3_CH_TX_PMA_RESET_DONE_ADDR, GTHE3_CH_TX_PMA_RESET_DONE_MASK, GTHE3_CH_TX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, tx_prgdiv_reset_done, GTHE3_CH_TX_PRGDIV_RESET_DONE_ADDR, GTHE3_CH_TX_PRGDIV_RESET_DONE_MASK, GTHE3_CH_TX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, tx_usrclk_act, GTHE3_CH_TX_USRCLK_ACT_ADDR, GTHE3_CH_TX_USRCLK_ACT_MASK, GTHE3_CH_TX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_pd, GTHE3_CH_TX_PD_ADDR, GTHE3_CH_TX_PD_MASK, GTHE3_CH_TX_PD_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_qpll_sel, GTHE3_CH_TX_QPLL_SEL_ADDR, GTHE3_CH_TX_QPLL_SEL_MASK, GTHE3_CH_TX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_polarity, GTHE3_CH_TX_POLARITY_ADDR, GTHE3_CH_TX_POLARITY_MASK, GTHE3_CH_TX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_elecidle, GTHE3_CH_TX_ELECIDLE_ADDR, GTHE3_CH_TX_ELECIDLE_MASK, GTHE3_CH_TX_ELECIDLE_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_inhibit, GTHE3_CH_TX_INHIBIT_ADDR, GTHE3_CH_TX_INHIBIT_MASK, GTHE3_CH_TX_INHIBIT_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_diffctrl, GTHE3_CH_TX_DIFFCTRL_ADDR, GTHE3_CH_TX_DIFFCTRL_MASK, GTHE3_CH_TX_DIFFCTRL_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_maincursor, GTHE3_CH_TX_MAINCURSOR_ADDR, GTHE3_CH_TX_MAINCURSOR_MASK, GTHE3_CH_TX_MAINCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_precursor, GTHE3_CH_TX_PRECURSOR_ADDR, GTHE3_CH_TX_PRECURSOR_MASK, GTHE3_CH_TX_PRECURSOR_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_postcursor, GTHE3_CH_TX_POSTCURSOR_ADDR, GTHE3_CH_TX_POSTCURSOR_MASK, GTHE3_CH_TX_POSTCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_prbs_sel, GTHE3_CH_TX_PRBS_SEL_ADDR, GTHE3_CH_TX_PRBS_SEL_MASK, GTHE3_CH_TX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe3, tx_prbs_forcerr, GTHE3_CH_TX_PRBS_FORCERR_ADDR, GTHE3_CH_TX_PRBS_FORCERR_MASK, GTHE3_CH_TX_PRBS_FORCERR_LSB); + +def_gt_ch_masked_reg_rw16(gthe3, rx_reset, GTHE3_CH_RX_RESET_ADDR, GTHE3_CH_RX_RESET_MASK, GTHE3_CH_RX_RESET_LSB); +int gthe3_ch_rx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe3, rx_pma_reset, GTHE3_CH_RX_PMA_RESET_ADDR, GTHE3_CH_RX_PMA_RESET_MASK, GTHE3_CH_RX_PMA_RESET_LSB); +int gthe3_ch_rx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe3, rx_pcs_reset, GTHE3_CH_RX_PCS_RESET_ADDR, GTHE3_CH_RX_PCS_RESET_MASK, GTHE3_CH_RX_PCS_RESET_LSB); +int gthe3_ch_rx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe3, rx_dfe_lpm_reset, GTHE3_CH_RX_DFE_LPM_RESET_ADDR, GTHE3_CH_RX_DFE_LPM_RESET_MASK, GTHE3_CH_RX_DFE_LPM_RESET_LSB); +int gthe3_ch_rx_dfe_lpm_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe3, eyescan_reset, GTHE3_CH_EYESCAN_RESET_ADDR, GTHE3_CH_EYESCAN_RESET_MASK, GTHE3_CH_EYESCAN_RESET_LSB); +int gthe3_ch_eyescan_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gthe3, rx_reset_done, GTHE3_CH_RX_RESET_DONE_ADDR, GTHE3_CH_RX_RESET_DONE_MASK, GTHE3_CH_RX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_gt_reset_done, GTHE3_CH_RX_GT_RESET_DONE_ADDR, GTHE3_CH_RX_GT_RESET_DONE_MASK, GTHE3_CH_RX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_pma_reset_done, GTHE3_CH_RX_PMA_RESET_DONE_ADDR, GTHE3_CH_RX_PMA_RESET_DONE_MASK, GTHE3_CH_RX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_prgdiv_reset_done, GTHE3_CH_RX_PRGDIV_RESET_DONE_ADDR, GTHE3_CH_RX_PRGDIV_RESET_DONE_MASK, GTHE3_CH_RX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_usrclk_act, GTHE3_CH_RX_USRCLK_ACT_ADDR, GTHE3_CH_RX_USRCLK_ACT_MASK, GTHE3_CH_RX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_pd, GTHE3_CH_RX_PD_ADDR, GTHE3_CH_RX_PD_MASK, GTHE3_CH_RX_PD_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_qpll_sel, GTHE3_CH_RX_QPLL_SEL_ADDR, GTHE3_CH_RX_QPLL_SEL_MASK, GTHE3_CH_RX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe3, loopback, GTHE3_CH_LOOPBACK_ADDR, GTHE3_CH_LOOPBACK_MASK, GTHE3_CH_LOOPBACK_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_polarity, GTHE3_CH_RX_POLARITY_ADDR, GTHE3_CH_RX_POLARITY_MASK, GTHE3_CH_RX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_cdr_hold, GTHE3_CH_RX_CDR_HOLD_ADDR, GTHE3_CH_RX_CDR_HOLD_MASK, GTHE3_CH_RX_CDR_HOLD_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_cdr_lock, GTHE3_CH_RX_CDR_LOCK_ADDR, GTHE3_CH_RX_CDR_LOCK_MASK, GTHE3_CH_RX_CDR_LOCK_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_lpm_en, GTHE3_CH_RX_LPM_EN_ADDR, GTHE3_CH_RX_LPM_EN_MASK, GTHE3_CH_RX_LPM_EN_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_dmonitor, GTHE3_CH_RX_DMONITOR_ADDR, GTHE3_CH_RX_DMONITOR_MASK, GTHE3_CH_RX_DMONITOR_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_prbs_sel, GTHE3_CH_RX_PRBS_SEL_ADDR, GTHE3_CH_RX_PRBS_SEL_MASK, GTHE3_CH_RX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_prbs_cnt_reset, GTHE3_CH_RX_PRBS_CNT_RESET_ADDR, GTHE3_CH_RX_PRBS_CNT_RESET_MASK, GTHE3_CH_RX_PRBS_CNT_RESET_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_prbs_locked, GTHE3_CH_RX_PRBS_LOCKED_ADDR, GTHE3_CH_RX_PRBS_LOCKED_MASK, GTHE3_CH_RX_PRBS_LOCKED_LSB); +def_gt_ch_masked_reg_read16(gthe3, rx_prbs_error, GTHE3_CH_RX_PRBS_ERROR_ADDR, GTHE3_CH_RX_PRBS_ERROR_MASK, GTHE3_CH_RX_PRBS_ERROR_LSB); + +// common +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cfg0, GTHE3_COM_QPLL0_CFG0_ADDR, GTHE3_COM_QPLL0_CFG0_MASK, GTHE3_COM_QPLL0_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, common_cfg0, GTHE3_COM_COMMON_CFG0_ADDR, GTHE3_COM_COMMON_CFG0_MASK, GTHE3_COM_COMMON_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, rsvd_attr0, GTHE3_COM_RSVD_ATTR0_ADDR, GTHE3_COM_RSVD_ATTR0_MASK, GTHE3_COM_RSVD_ATTR0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cfg1, GTHE3_COM_QPLL0_CFG1_ADDR, GTHE3_COM_QPLL0_CFG1_MASK, GTHE3_COM_QPLL0_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cfg2, GTHE3_COM_QPLL0_CFG2_ADDR, GTHE3_COM_QPLL0_CFG2_MASK, GTHE3_COM_QPLL0_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_lock_cfg, GTHE3_COM_QPLL0_LOCK_CFG_ADDR, GTHE3_COM_QPLL0_LOCK_CFG_MASK, GTHE3_COM_QPLL0_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_init_cfg0, GTHE3_COM_QPLL0_INIT_CFG0_ADDR, GTHE3_COM_QPLL0_INIT_CFG0_MASK, GTHE3_COM_QPLL0_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_init_cfg1, GTHE3_COM_QPLL0_INIT_CFG1_ADDR, GTHE3_COM_QPLL0_INIT_CFG1_MASK, GTHE3_COM_QPLL0_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_fbdiv, GTHE3_COM_QPLL0_FBDIV_ADDR, GTHE3_COM_QPLL0_FBDIV_MASK, GTHE3_COM_QPLL0_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cfg3, GTHE3_COM_QPLL0_CFG3_ADDR, GTHE3_COM_QPLL0_CFG3_MASK, GTHE3_COM_QPLL0_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cp, GTHE3_COM_QPLL0_CP_ADDR, GTHE3_COM_QPLL0_CP_MASK, GTHE3_COM_QPLL0_CP_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_refclk_div, GTHE3_COM_QPLL0_REFCLK_DIV_ADDR, GTHE3_COM_QPLL0_REFCLK_DIV_MASK, GTHE3_COM_QPLL0_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_lpf, GTHE3_COM_QPLL0_LPF_ADDR, GTHE3_COM_QPLL0_LPF_MASK, GTHE3_COM_QPLL0_LPF_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cfg1_g3, GTHE3_COM_QPLL0_CFG1_G3_ADDR, GTHE3_COM_QPLL0_CFG1_G3_MASK, GTHE3_COM_QPLL0_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cfg2_g3, GTHE3_COM_QPLL0_CFG2_G3_ADDR, GTHE3_COM_QPLL0_CFG2_G3_MASK, GTHE3_COM_QPLL0_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_lpf_g3, GTHE3_COM_QPLL0_LPF_G3_ADDR, GTHE3_COM_QPLL0_LPF_G3_MASK, GTHE3_COM_QPLL0_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_lock_cfg_g3, GTHE3_COM_QPLL0_LOCK_CFG_G3_ADDR, GTHE3_COM_QPLL0_LOCK_CFG_G3_MASK, GTHE3_COM_QPLL0_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, rsvd_attr1, GTHE3_COM_RSVD_ATTR1_ADDR, GTHE3_COM_RSVD_ATTR1_MASK, GTHE3_COM_RSVD_ATTR1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_fbdiv_g3, GTHE3_COM_QPLL0_FBDIV_G3_ADDR, GTHE3_COM_QPLL0_FBDIV_G3_MASK, GTHE3_COM_QPLL0_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, rxrecclkout0_sel, GTHE3_COM_RXRECCLKOUT0_SEL_ADDR, GTHE3_COM_RXRECCLKOUT0_SEL_MASK, GTHE3_COM_RXRECCLKOUT0_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_sdm_cfg0, GTHE3_COM_QPLL0_SDM_CFG0_ADDR, GTHE3_COM_QPLL0_SDM_CFG0_MASK, GTHE3_COM_QPLL0_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_sdm_cfg1, GTHE3_COM_QPLL0_SDM_CFG1_ADDR, GTHE3_COM_QPLL0_SDM_CFG1_MASK, GTHE3_COM_QPLL0_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm0initseed0_0, GTHE3_COM_SDM0INITSEED0_0_ADDR, GTHE3_COM_SDM0INITSEED0_0_MASK, GTHE3_COM_SDM0INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm0initseed0_1, GTHE3_COM_SDM0INITSEED0_1_ADDR, GTHE3_COM_SDM0INITSEED0_1_MASK, GTHE3_COM_SDM0INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_sdm_cfg2, GTHE3_COM_QPLL0_SDM_CFG2_ADDR, GTHE3_COM_QPLL0_SDM_CFG2_MASK, GTHE3_COM_QPLL0_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cp_g3, GTHE3_COM_QPLL0_CP_G3_ADDR, GTHE3_COM_QPLL0_CP_G3_MASK, GTHE3_COM_QPLL0_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm0data1_0, GTHE3_COM_SDM0DATA1_0_ADDR, GTHE3_COM_SDM0DATA1_0_MASK, GTHE3_COM_SDM0DATA1_0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm0_width_pin_sel, GTHE3_COM_SDM0_WIDTH_PIN_SEL_ADDR, GTHE3_COM_SDM0_WIDTH_PIN_SEL_MASK, GTHE3_COM_SDM0_WIDTH_PIN_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm0_data_pin_sel, GTHE3_COM_SDM0_DATA_PIN_SEL_ADDR, GTHE3_COM_SDM0_DATA_PIN_SEL_MASK, GTHE3_COM_SDM0_DATA_PIN_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm0data1_1, GTHE3_COM_SDM0DATA1_1_ADDR, GTHE3_COM_SDM0DATA1_1_MASK, GTHE3_COM_SDM0DATA1_1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll0_cfg4, GTHE3_COM_QPLL0_CFG4_ADDR, GTHE3_COM_QPLL0_CFG4_MASK, GTHE3_COM_QPLL0_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gthe3, bias_cfg0, GTHE3_COM_BIAS_CFG0_ADDR, GTHE3_COM_BIAS_CFG0_MASK, GTHE3_COM_BIAS_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, bias_cfg1, GTHE3_COM_BIAS_CFG1_ADDR, GTHE3_COM_BIAS_CFG1_MASK, GTHE3_COM_BIAS_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, bias_cfg2, GTHE3_COM_BIAS_CFG2_ADDR, GTHE3_COM_BIAS_CFG2_MASK, GTHE3_COM_BIAS_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe3, bias_cfg3, GTHE3_COM_BIAS_CFG3_ADDR, GTHE3_COM_BIAS_CFG3_MASK, GTHE3_COM_BIAS_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, bias_cfg_rsvd, GTHE3_COM_BIAS_CFG_RSVD_ADDR, GTHE3_COM_BIAS_CFG_RSVD_MASK, GTHE3_COM_BIAS_CFG_RSVD_LSB); +def_gt_pll_masked_reg_rw16(gthe3, bias_cfg4, GTHE3_COM_BIAS_CFG4_ADDR, GTHE3_COM_BIAS_CFG4_MASK, GTHE3_COM_BIAS_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cfg0, GTHE3_COM_QPLL1_CFG0_ADDR, GTHE3_COM_QPLL1_CFG0_MASK, GTHE3_COM_QPLL1_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, common_cfg1, GTHE3_COM_COMMON_CFG1_ADDR, GTHE3_COM_COMMON_CFG1_MASK, GTHE3_COM_COMMON_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, por_cfg, GTHE3_COM_POR_CFG_ADDR, GTHE3_COM_POR_CFG_MASK, GTHE3_COM_POR_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cfg1, GTHE3_COM_QPLL1_CFG1_ADDR, GTHE3_COM_QPLL1_CFG1_MASK, GTHE3_COM_QPLL1_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cfg2, GTHE3_COM_QPLL1_CFG2_ADDR, GTHE3_COM_QPLL1_CFG2_MASK, GTHE3_COM_QPLL1_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_lock_cfg, GTHE3_COM_QPLL1_LOCK_CFG_ADDR, GTHE3_COM_QPLL1_LOCK_CFG_MASK, GTHE3_COM_QPLL1_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_init_cfg0, GTHE3_COM_QPLL1_INIT_CFG0_ADDR, GTHE3_COM_QPLL1_INIT_CFG0_MASK, GTHE3_COM_QPLL1_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_init_cfg1, GTHE3_COM_QPLL1_INIT_CFG1_ADDR, GTHE3_COM_QPLL1_INIT_CFG1_MASK, GTHE3_COM_QPLL1_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_fbdiv, GTHE3_COM_QPLL1_FBDIV_ADDR, GTHE3_COM_QPLL1_FBDIV_MASK, GTHE3_COM_QPLL1_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cfg3, GTHE3_COM_QPLL1_CFG3_ADDR, GTHE3_COM_QPLL1_CFG3_MASK, GTHE3_COM_QPLL1_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cp, GTHE3_COM_QPLL1_CP_ADDR, GTHE3_COM_QPLL1_CP_MASK, GTHE3_COM_QPLL1_CP_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sarc_sel, GTHE3_COM_SARC_SEL_ADDR, GTHE3_COM_SARC_SEL_MASK, GTHE3_COM_SARC_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sarc_en, GTHE3_COM_SARC_EN_ADDR, GTHE3_COM_SARC_EN_MASK, GTHE3_COM_SARC_EN_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_refclk_div, GTHE3_COM_QPLL1_REFCLK_DIV_ADDR, GTHE3_COM_QPLL1_REFCLK_DIV_MASK, GTHE3_COM_QPLL1_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_lpf, GTHE3_COM_QPLL1_LPF_ADDR, GTHE3_COM_QPLL1_LPF_MASK, GTHE3_COM_QPLL1_LPF_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cfg1_g3, GTHE3_COM_QPLL1_CFG1_G3_ADDR, GTHE3_COM_QPLL1_CFG1_G3_MASK, GTHE3_COM_QPLL1_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cfg2_g3, GTHE3_COM_QPLL1_CFG2_G3_ADDR, GTHE3_COM_QPLL1_CFG2_G3_MASK, GTHE3_COM_QPLL1_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_lpf_g3, GTHE3_COM_QPLL1_LPF_G3_ADDR, GTHE3_COM_QPLL1_LPF_G3_MASK, GTHE3_COM_QPLL1_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_lock_cfg_g3, GTHE3_COM_QPLL1_LOCK_CFG_G3_ADDR, GTHE3_COM_QPLL1_LOCK_CFG_G3_MASK, GTHE3_COM_QPLL1_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, rsvd_attr2, GTHE3_COM_RSVD_ATTR2_ADDR, GTHE3_COM_RSVD_ATTR2_MASK, GTHE3_COM_RSVD_ATTR2_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_fbdiv_g3, GTHE3_COM_QPLL1_FBDIV_G3_ADDR, GTHE3_COM_QPLL1_FBDIV_G3_MASK, GTHE3_COM_QPLL1_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, rxrecclkout1_sel, GTHE3_COM_RXRECCLKOUT1_SEL_ADDR, GTHE3_COM_RXRECCLKOUT1_SEL_MASK, GTHE3_COM_RXRECCLKOUT1_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_sdm_cfg0, GTHE3_COM_QPLL1_SDM_CFG0_ADDR, GTHE3_COM_QPLL1_SDM_CFG0_MASK, GTHE3_COM_QPLL1_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_sdm_cfg1, GTHE3_COM_QPLL1_SDM_CFG1_ADDR, GTHE3_COM_QPLL1_SDM_CFG1_MASK, GTHE3_COM_QPLL1_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm1initseed0_0, GTHE3_COM_SDM1INITSEED0_0_ADDR, GTHE3_COM_SDM1INITSEED0_0_MASK, GTHE3_COM_SDM1INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm1initseed0_1, GTHE3_COM_SDM1INITSEED0_1_ADDR, GTHE3_COM_SDM1INITSEED0_1_MASK, GTHE3_COM_SDM1INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_sdm_cfg2, GTHE3_COM_QPLL1_SDM_CFG2_ADDR, GTHE3_COM_QPLL1_SDM_CFG2_MASK, GTHE3_COM_QPLL1_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cp_g3, GTHE3_COM_QPLL1_CP_G3_ADDR, GTHE3_COM_QPLL1_CP_G3_MASK, GTHE3_COM_QPLL1_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm1data1_0, GTHE3_COM_SDM1DATA1_0_ADDR, GTHE3_COM_SDM1DATA1_0_MASK, GTHE3_COM_SDM1DATA1_0_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm1_width_pin_sel, GTHE3_COM_SDM1_WIDTH_PIN_SEL_ADDR, GTHE3_COM_SDM1_WIDTH_PIN_SEL_MASK, GTHE3_COM_SDM1_WIDTH_PIN_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm1_data_pin_sel, GTHE3_COM_SDM1_DATA_PIN_SEL_ADDR, GTHE3_COM_SDM1_DATA_PIN_SEL_MASK, GTHE3_COM_SDM1_DATA_PIN_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe3, sdm1data1_1, GTHE3_COM_SDM1DATA1_1_ADDR, GTHE3_COM_SDM1DATA1_1_MASK, GTHE3_COM_SDM1DATA1_1_LSB); +def_gt_pll_masked_reg_rw16(gthe3, rsvd_attr3, GTHE3_COM_RSVD_ATTR3_ADDR, GTHE3_COM_RSVD_ATTR3_MASK, GTHE3_COM_RSVD_ATTR3_LSB); +def_gt_pll_masked_reg_rw16(gthe3, qpll1_cfg4, GTHE3_COM_QPLL1_CFG4_ADDR, GTHE3_COM_QPLL1_CFG4_MASK, GTHE3_COM_QPLL1_CFG4_LSB); + +// RX +def_gt_ch_masked_reg_rw16(gthe3, rx_data_width_raw, GTHE3_CH_RX_DATA_WIDTH_ADDR, GTHE3_CH_RX_DATA_WIDTH_MASK, GTHE3_CH_RX_DATA_WIDTH_LSB); +int gthe3_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gthe3, rx_int_data_width_raw, GTHE3_CH_RX_INT_DATAWIDTH_ADDR, GTHE3_CH_RX_INT_DATAWIDTH_MASK, GTHE3_CH_RX_INT_DATAWIDTH_LSB); +int gthe3_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gthe3, es_prescale, GTHE3_CH_ES_PRESCALE_ADDR, GTHE3_CH_ES_PRESCALE_MASK, GTHE3_CH_ES_PRESCALE_LSB); +def_gt_ch_masked_reg_rw16(gthe3, es_eye_scan_en, GTHE3_CH_ES_EYE_SCAN_EN_ADDR, GTHE3_CH_ES_EYE_SCAN_EN_MASK, GTHE3_CH_ES_EYE_SCAN_EN_LSB); +def_gt_ch_masked_reg_rw16(gthe3, es_errdet_en, GTHE3_CH_ES_ERRDET_EN_ADDR, GTHE3_CH_ES_ERRDET_EN_MASK, GTHE3_CH_ES_ERRDET_EN_LSB); +def_gt_ch_masked_reg_rw16(gthe3, es_control, GTHE3_CH_ES_CONTROL_ADDR, GTHE3_CH_ES_CONTROL_MASK, GTHE3_CH_ES_CONTROL_LSB); + +int gthe3_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask); +int gthe3_ch_set_es_qual_mask_clear(struct gt_ch *ch); + +int gthe3_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask); +int gthe3_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width); + +def_gt_ch_masked_reg_rw16(gthe3, es_horz_offset, GTHE3_CH_ES_HORZ_OFFSET_ADDR, GTHE3_CH_ES_HORZ_OFFSET_MASK, GTHE3_CH_ES_HORZ_OFFSET_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_eyescan_vs_range, GTHE3_CH_RX_EYESCAN_VS_RANGE_ADDR, GTHE3_CH_RX_EYESCAN_VS_RANGE_MASK, GTHE3_CH_RX_EYESCAN_VS_RANGE_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_eyescan_vs_code, GTHE3_CH_RX_EYESCAN_VS_CODE_ADDR, GTHE3_CH_RX_EYESCAN_VS_CODE_MASK, GTHE3_CH_RX_EYESCAN_VS_CODE_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_eyescan_vs_ut_sign, GTHE3_CH_RX_EYESCAN_VS_UT_SIGN_ADDR, GTHE3_CH_RX_EYESCAN_VS_UT_SIGN_MASK, GTHE3_CH_RX_EYESCAN_VS_UT_SIGN_LSB); +def_gt_ch_masked_reg_rw16(gthe3, rx_eyescan_vs_neg_dir, GTHE3_CH_RX_EYESCAN_VS_NEG_DIR_ADDR, GTHE3_CH_RX_EYESCAN_VS_NEG_DIR_MASK, GTHE3_CH_RX_EYESCAN_VS_NEG_DIR_LSB); +def_gt_ch_masked_reg_read16(gthe3, es_error_count, GTHE3_CH_ES_ERROR_COUNT_ADDR, GTHE3_CH_ES_ERROR_COUNT_MASK, GTHE3_CH_ES_ERROR_COUNT_LSB); +def_gt_ch_masked_reg_read16(gthe3, es_sample_count, GTHE3_CH_ES_SAMPLE_COUNT_ADDR, GTHE3_CH_ES_SAMPLE_COUNT_MASK, GTHE3_CH_ES_SAMPLE_COUNT_LSB); +def_gt_ch_masked_reg_read16(gthe3, es_control_status, GTHE3_CH_ES_CONTROL_STATUS_ADDR, GTHE3_CH_ES_CONTROL_STATUS_MASK, GTHE3_CH_ES_CONTROL_STATUS_LSB); + +int gthe3_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val); + +// TX +def_gt_ch_masked_reg_rw16(gthe3, tx_data_width_raw, GTHE3_CH_TX_DATA_WIDTH_ADDR, GTHE3_CH_TX_DATA_WIDTH_MASK, GTHE3_CH_TX_DATA_WIDTH_LSB); +int gthe3_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gthe3, tx_int_data_width_raw, GTHE3_CH_TX_INT_DATAWIDTH_ADDR, GTHE3_CH_TX_INT_DATAWIDTH_MASK, GTHE3_CH_TX_INT_DATAWIDTH_LSB); +int gthe3_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val); + +extern const struct gt_quad_ops gthe3_gt_quad_ops; + +#endif /* XCVR_GTHE3_H */ diff --git a/utils/xcvr_gthe4.c b/utils/xcvr_gthe4.c new file mode 100644 index 000000000..bef83fa39 --- /dev/null +++ b/utils/xcvr_gthe4.c @@ -0,0 +1,672 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include +#include +#include "xcvr_gthe4.h" + +// signals +int gthe4_pll_qpll0_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gthe4_pll_set_qpll0_reset(pll, 1); + + if (ret) + return ret; + + return gthe4_pll_set_qpll0_reset(pll, 0); +} + +int gthe4_pll_qpll1_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gthe4_pll_set_qpll1_reset(pll, 1); + + if (ret) + return ret; + + return gthe4_pll_set_qpll1_reset(pll, 0); +} + +int gthe4_ch_tx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_tx_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_tx_reset(ch, 0); +} + +int gthe4_ch_tx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_tx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_tx_pma_reset(ch, 0); +} + +int gthe4_ch_tx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_tx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_tx_pcs_reset(ch, 0); +} + +int gthe4_ch_rx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_rx_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_rx_reset(ch, 0); +} + +int gthe4_ch_rx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_rx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_rx_pma_reset(ch, 0); +} + +int gthe4_ch_rx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_rx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_rx_pcs_reset(ch, 0); +} + +int gthe4_ch_rx_dfe_lpm_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_rx_dfe_lpm_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_rx_dfe_lpm_reset(ch, 0); +} + +int gthe4_ch_eyescan_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gthe4_ch_set_eyescan_reset(ch, 1); + + if (ret) + return ret; + + return gthe4_ch_set_eyescan_reset(ch, 0); +} + +// RX +int gthe4_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gthe4_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gthe4_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gthe4_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gthe4_ch_get_rx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gthe4_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_QUAL_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_QUAL_MASK5_ADDR+k, mask[2*k+10] | (mask[2*k+11] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gthe4_ch_set_es_qual_mask_clear(struct gt_ch *ch) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_QUAL_MASK0_ADDR+k, 0xffff); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_QUAL_MASK5_ADDR+k, 0xffff); + if (ret) + return ret; + } + + return 0; +} + +int gthe4_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_SDATA_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_SDATA_MASK5_ADDR+k, mask[2*k+10] | (mask[2*k+11] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gthe4_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + int shift = width - (80 - ((k+1)*16)); + uint32_t mask = 0xffff; + + if (shift < 0) + { + mask = 0xffff; + } + else if (shift > 16) + { + mask = 0x0000; + } + else + { + mask = 0xffff >> shift; + } + + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_SDATA_MASK0_ADDR+k, mask); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTHE4_CH_ES_SDATA_MASK5_ADDR+k, 0xffff); + if (ret) + return ret; + } + + return 0; +} + +int gthe4_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t v1, v2; + + ret = gt_ch_reg_read(ch, GTHE4_CH_RX_PRBS_ERR_CNT_L_ADDR | (ch->index << 17), &v1); + if (ret) + return ret; + + ret = gt_ch_reg_read(ch, GTHE4_CH_RX_PRBS_ERR_CNT_H_ADDR | (ch->index << 17), &v2); + if (ret) + return ret; + + *val = v1 | (v2 << 16); + return 0; +} + +// TX +int gthe4_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gthe4_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gthe4_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gthe4_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gthe4_ch_get_tx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +struct gthe4_ch_priv { + uint32_t tx_data_width; + uint32_t tx_int_data_width; + uint32_t rx_data_width; + uint32_t rx_int_data_width; + int dfe_en; + + int prescale; + int h_start; + int h_stop; + int h_step; + int v_range; + int v_start; + int v_stop; + int v_step; + + int h_offset; + int v_offset; + int ut_sign; + int eyescan_running; +}; + +static const struct gt_reg_val gthe4_ch_preset_10g_dfe_regs[] = { + {GTHE4_CH_RX_SUM_IREF_TUNE_ADDR, GTHE4_CH_RX_SUM_IREF_TUNE_MASK, GTHE4_CH_RX_SUM_IREF_TUNE_LSB, 0x0009}, + {GTHE4_CH_RX_SUM_VCMTUNE_ADDR, GTHE4_CH_RX_SUM_VCMTUNE_MASK, GTHE4_CH_RX_SUM_VCMTUNE_LSB, 0x000A}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gthe4_ch_preset_10g_lpm_regs[] = { + {GTHE4_CH_RX_SUM_IREF_TUNE_ADDR, GTHE4_CH_RX_SUM_IREF_TUNE_MASK, GTHE4_CH_RX_SUM_IREF_TUNE_LSB, 0x0004}, + {GTHE4_CH_RX_SUM_VCMTUNE_ADDR, GTHE4_CH_RX_SUM_VCMTUNE_MASK, GTHE4_CH_RX_SUM_VCMTUNE_LSB, 0x0006}, + {0, 0, 0, 0} +}; + +static const uint32_t gthe4_ch_presets[] = { + GT_PRESET_10G_DFE, + GT_PRESET_10G_LPM, + 0 +}; + +static int gthe4_ch_get_available_presets(struct gt_ch *ch, const uint32_t **presets) +{ + *presets = gthe4_ch_presets; + return 0; +} + +int gthe4_ch_load_preset(struct gt_ch *ch, uint32_t preset) +{ + if (preset == GT_PRESET_10G_DFE || preset == GT_PRESET_10G_LPM) + { + gthe4_ch_set_tx_reset(ch, 1); + gthe4_ch_set_rx_reset(ch, 1); + + if (preset == GT_PRESET_10G_DFE) + { + gt_ch_reg_write_multiple(ch, gthe4_ch_preset_10g_dfe_regs); + gthe4_ch_set_rx_lpm_en(ch, 0); + } + else + { + gt_ch_reg_write_multiple(ch, gthe4_ch_preset_10g_lpm_regs); + gthe4_ch_set_rx_lpm_en(ch, 1); + } + + gthe4_ch_set_tx_reset(ch, 0); + gthe4_ch_set_rx_reset(ch, 0); + + return 0; + } + + return -1; +} + +static int gthe4_ch_eyescan_start(struct gt_ch *ch, struct gt_eyescan_params *params) +{ + struct gthe4_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + float ber; + + priv->eyescan_running = 0; + + gthe4_ch_get_rx_lpm_en(ch, &val); + priv->dfe_en = !val; + + gthe4_ch_get_rx_data_width(ch, &priv->rx_data_width); + gthe4_ch_get_rx_int_data_width(ch, &priv->rx_int_data_width); + + priv->prescale = 0; + + for (priv->prescale = 0; priv->prescale < 32; priv->prescale++) + { + if (((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale) >= params->target_bit_count) + break; + } + + params->target_bit_count = ((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + params->h_range = 0; + + priv->h_start = params->h_start; + priv->h_stop = params->h_stop; + priv->h_step = params->h_step; + priv->v_range = params->v_range; + priv->v_start = params->v_start; + priv->v_stop = params->v_stop; + priv->v_step = params->v_step; + + gthe4_ch_set_es_control(ch, 0x00); + + gthe4_ch_set_es_prescale(ch, 4); + gthe4_ch_set_es_errdet_en(ch, 1); + + gthe4_ch_set_es_qual_mask_clear(ch); + gthe4_ch_set_es_sdata_mask_width(ch, priv->rx_int_data_width); + + gthe4_ch_set_rx_eyescan_vs_range(ch, priv->v_range); + + gthe4_ch_set_es_horz_offset(ch, 0x000); + gthe4_ch_set_rx_eyescan_vs_neg_dir(ch, 0); + gthe4_ch_set_rx_eyescan_vs_code(ch, 0); + gthe4_ch_set_rx_eyescan_vs_ut_sign(ch, 0); + + gthe4_ch_set_es_eye_scan_en(ch, 1); + + gthe4_ch_rx_pma_reset(ch); + + for (int ber_tries = 0; ber_tries < 10; ber_tries++) + { + for (int reset_tries = 0; reset_tries < 30; reset_tries++) + { + gthe4_ch_get_rx_reset_done(ch, &val); + if (val) + break; + usleep(100000); + } + + if (!val) + { + fprintf(stderr, "Error: channel stuck in reset\n"); + return -1; + } + + usleep(100000); + + // check for lock + gthe4_ch_set_es_control(ch, 0x01); + + for (int wait_tries = 0; wait_tries < 30; wait_tries++) + { + gthe4_ch_get_es_control_status(ch, &val); + if (val & 1) + break; + usleep(100000); + } + + if (!(val & 1)) + { + fprintf(stderr, "Error: eye scan did not finish (%d)\n", val); + return -1; + } + + gthe4_ch_set_es_control(ch, 0x00); + + gthe4_ch_get_es_error_count(ch, &error_count); + gthe4_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+4); + + ber = (float)error_count / (float)bit_count; + + if (ber < 0.01) + break; + + printf("High BER (%02f), resetting eye scan logic\n", ber); + + gthe4_ch_set_es_horz_offset(ch, 0x880); + gthe4_ch_set_eyescan_reset(ch, 1); + gthe4_ch_set_es_horz_offset(ch, 0x800); + gthe4_ch_set_eyescan_reset(ch, 0); + } + + if (ber > 0.01) + { + fprintf(stderr, "Error: High BER, alignment failed\n"); + return -1; + } + + // set up for measurement + priv->h_offset = priv->h_start; + priv->v_offset = priv->v_start; + priv->ut_sign = 0; + + gthe4_ch_set_es_control(ch, 0x00); + gthe4_ch_set_es_prescale(ch, priv->prescale); + gthe4_ch_set_es_errdet_en(ch, 1); + gthe4_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | (priv->h_offset < 0 ? 0x800 : 0x000)); + gthe4_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gthe4_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + gthe4_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + // start measurement + gthe4_ch_set_es_control(ch, 0x01); + + priv->eyescan_running = 1; + + return 0; +} + +static int gthe4_ch_eyescan_step(struct gt_ch *ch, struct gt_eyescan_point *point) +{ + struct gthe4_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + + int restart = 0; + + if (!priv->eyescan_running) + return 0; + + gthe4_ch_get_es_control_status(ch, &val); + if (!(val & 1)) + return 2; + + gthe4_ch_set_es_control(ch, 0x00); + + gthe4_ch_get_es_error_count(ch, &error_count); + gthe4_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + + point->error_count = error_count; + point->bit_count = bit_count; + point->x = priv->h_offset; + point->y = priv->v_offset; + point->ut_sign = priv->ut_sign; + + restart = 0; + + if (!priv->ut_sign && priv->dfe_en) + { + priv->ut_sign = 1; + restart = 1; + } + else + { + priv->ut_sign = 0; + } + + gthe4_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + if (restart) + { + gthe4_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->v_offset < priv->v_stop) + { + priv->v_offset += priv->v_step; + restart = 1; + } + else + { + priv->v_offset = priv->v_start; + } + + gthe4_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gthe4_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + + if (restart) + { + gthe4_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->h_offset < priv->h_stop) + { + priv->h_offset += priv->h_step; + restart = 1; + } + else + { + // done + priv->eyescan_running = 0; + return 1; + } + + gthe4_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | (priv->h_offset < 0 ? 0x800 : 0x000)); + + if (restart) + { + gthe4_ch_set_es_control(ch, 0x01); + return 1; + } + + priv->eyescan_running = 0; + return 0; +} + +const struct gt_ch_ops gthe4_gt_ch_ops = { + .get_tx_reset = gthe4_ch_get_tx_reset, + .set_tx_reset = gthe4_ch_set_tx_reset, + .tx_reset = gthe4_ch_tx_reset, + .get_rx_reset = gthe4_ch_get_rx_reset, + .set_rx_reset = gthe4_ch_set_rx_reset, + .rx_reset = gthe4_ch_rx_reset, + .get_tx_data_width = gthe4_ch_get_tx_data_width, + .get_tx_int_data_width = gthe4_ch_get_tx_int_data_width, + .get_rx_data_width = gthe4_ch_get_rx_data_width, + .get_rx_int_data_width = gthe4_ch_get_rx_int_data_width, + .get_available_presets = gthe4_ch_get_available_presets, + .load_preset = gthe4_ch_load_preset, + .eyescan_start = gthe4_ch_eyescan_start, + .eyescan_step = gthe4_ch_eyescan_step +}; + +static int gthe4_ch_init(struct gt_ch *ch) +{ + struct gthe4_ch_priv *priv = calloc(1, sizeof(struct gthe4_ch_priv)); + if (!priv) + return -1; + + ch->priv = priv; + + return 0; +} + +int gthe4_quad_init(struct gt_quad *quad) +{ + quad->type = "GTHE4"; + + for (int n = 0; n < quad->ch_count; n++) + { + quad->ch[n].quad = quad; + quad->ch[n].pll = &quad->pll; + quad->ch[n].ops = >he4_gt_ch_ops; + quad->ch[n].index = n; + + gthe4_ch_init(&quad->ch[n]); + } + + return 0; +} + +const struct gt_quad_ops gthe4_gt_quad_ops = { + .init = gthe4_quad_init +}; diff --git a/utils/xcvr_gthe4.h b/utils/xcvr_gthe4.h new file mode 100644 index 000000000..335c0111f --- /dev/null +++ b/utils/xcvr_gthe4.h @@ -0,0 +1,411 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#ifndef XCVR_GTHE4_H +#define XCVR_GTHE4_H + +#include "xcvr_gt.h" +#include "gt/gthe4_regs.h" + +// signals +#define GTHE4_COM_QPLL0_RESET_ADDR 0x10000 +#define GTHE4_COM_QPLL0_RESET_MSB 0 +#define GTHE4_COM_QPLL0_RESET_LSB 0 +#define GTHE4_COM_QPLL0_RESET_MASK BIT_MASK(GTHE4_COM_QPLL0_RESET_MSB, GTHE4_COM_QPLL0_RESET_LSB) +#define GTHE4_COM_QPLL0_LOCK_ADDR 0x10000 +#define GTHE4_COM_QPLL0_LOCK_MSB 8 +#define GTHE4_COM_QPLL0_LOCK_LSB 8 +#define GTHE4_COM_QPLL0_LOCK_MASK BIT_MASK(GTHE4_COM_QPLL0_LOCK_MSB, GTHE4_COM_QPLL0_LOCK_LSB) +#define GTHE4_COM_QPLL0_PD_ADDR 0x10001 +#define GTHE4_COM_QPLL0_PD_MSB 0 +#define GTHE4_COM_QPLL0_PD_LSB 0 +#define GTHE4_COM_QPLL0_PD_MASK BIT_MASK(GTHE4_COM_QPLL0_PD_MSB, GTHE4_COM_QPLL0_PD_LSB) +#define GTHE4_COM_QPLL1_RESET_ADDR 0x11000 +#define GTHE4_COM_QPLL1_RESET_MSB 0 +#define GTHE4_COM_QPLL1_RESET_LSB 0 +#define GTHE4_COM_QPLL1_RESET_MASK BIT_MASK(GTHE4_COM_QPLL0_RESET_MSB, GTHE4_COM_QPLL0_RESET_LSB) +#define GTHE4_COM_QPLL1_LOCK_ADDR 0x11000 +#define GTHE4_COM_QPLL1_LOCK_MSB 8 +#define GTHE4_COM_QPLL1_LOCK_LSB 8 +#define GTHE4_COM_QPLL1_LOCK_MASK BIT_MASK(GTHE4_COM_QPLL0_LOCK_MSB, GTHE4_COM_QPLL0_LOCK_LSB) +#define GTHE4_COM_QPLL1_PD_ADDR 0x11001 +#define GTHE4_COM_QPLL1_PD_MSB 0 +#define GTHE4_COM_QPLL1_PD_LSB 0 +#define GTHE4_COM_QPLL1_PD_MASK BIT_MASK(GTHE4_COM_QPLL1_PD_MSB, GTHE4_COM_QPLL1_PD_LSB) + +#define GTHE4_CH_TX_RESET_ADDR 0x10000 +#define GTHE4_CH_TX_RESET_MSB 0 +#define GTHE4_CH_TX_RESET_LSB 0 +#define GTHE4_CH_TX_RESET_MASK BIT_MASK(GTHE4_CH_TX_RESET_MSB, GTHE4_CH_TX_RESET_LSB) +#define GTHE4_CH_TX_PMA_RESET_ADDR 0x10000 +#define GTHE4_CH_TX_PMA_RESET_MSB 1 +#define GTHE4_CH_TX_PMA_RESET_LSB 1 +#define GTHE4_CH_TX_PMA_RESET_MASK BIT_MASK(GTHE4_CH_TX_PMA_RESET_MSB, GTHE4_CH_TX_PMA_RESET_LSB) +#define GTHE4_CH_TX_PCS_RESET_ADDR 0x10000 +#define GTHE4_CH_TX_PCS_RESET_MSB 2 +#define GTHE4_CH_TX_PCS_RESET_LSB 2 +#define GTHE4_CH_TX_PCS_RESET_MASK BIT_MASK(GTHE4_CH_TX_PCS_RESET_MSB, GTHE4_CH_TX_PCS_RESET_LSB) +#define GTHE4_CH_TX_RESET_DONE_ADDR 0x10000 +#define GTHE4_CH_TX_RESET_DONE_MSB 8 +#define GTHE4_CH_TX_RESET_DONE_LSB 8 +#define GTHE4_CH_TX_RESET_DONE_MASK BIT_MASK(GTHE4_CH_TX_RESET_DONE_MSB, GTHE4_CH_TX_RESET_DONE_LSB) +#define GTHE4_CH_TX_GT_RESET_DONE_ADDR 0x10000 +#define GTHE4_CH_TX_GT_RESET_DONE_MSB 9 +#define GTHE4_CH_TX_GT_RESET_DONE_LSB 9 +#define GTHE4_CH_TX_GT_RESET_DONE_MASK BIT_MASK(GTHE4_CH_TX_GT_RESET_DONE_MSB, GTHE4_CH_TX_GT_RESET_DONE_LSB) +#define GTHE4_CH_TX_PMA_RESET_DONE_ADDR 0x10000 +#define GTHE4_CH_TX_PMA_RESET_DONE_MSB 10 +#define GTHE4_CH_TX_PMA_RESET_DONE_LSB 10 +#define GTHE4_CH_TX_PMA_RESET_DONE_MASK BIT_MASK(GTHE4_CH_TX_PMA_RESET_DONE_MSB, GTHE4_CH_TX_PMA_RESET_DONE_LSB) +#define GTHE4_CH_TX_PRGDIV_RESET_DONE_ADDR 0x10000 +#define GTHE4_CH_TX_PRGDIV_RESET_DONE_MSB 11 +#define GTHE4_CH_TX_PRGDIV_RESET_DONE_LSB 11 +#define GTHE4_CH_TX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTHE4_CH_TX_PRGDIV_RESET_DONE_MSB, GTHE4_CH_TX_PRGDIV_RESET_DONE_LSB) +#define GTHE4_CH_TX_USRCLK_ACT_ADDR 0x10000 +#define GTHE4_CH_TX_USRCLK_ACT_MSB 12 +#define GTHE4_CH_TX_USRCLK_ACT_LSB 12 +#define GTHE4_CH_TX_USRCLK_ACT_MASK BIT_MASK(GTHE4_CH_TX_USRCLK_ACT_MSB, GTHE4_CH_TX_USRCLK_ACT_LSB) +#define GTHE4_CH_TX_PD_ADDR 0x10001 +#define GTHE4_CH_TX_PD_MSB 0 +#define GTHE4_CH_TX_PD_LSB 0 +#define GTHE4_CH_TX_PD_MASK BIT_MASK(GTHE4_CH_TX_PD_MSB, GTHE4_CH_TX_PD_LSB) +#define GTHE4_CH_TX_QPLL_SEL_ADDR 0x10001 +#define GTHE4_CH_TX_QPLL_SEL_MSB 1 +#define GTHE4_CH_TX_QPLL_SEL_LSB 1 +#define GTHE4_CH_TX_QPLL_SEL_MASK BIT_MASK(GTHE4_CH_TX_QPLL_SEL_MSB, GTHE4_CH_TX_QPLL_SEL_LSB) +#define GTHE4_CH_TX_POLARITY_ADDR 0x10010 +#define GTHE4_CH_TX_POLARITY_MSB 0 +#define GTHE4_CH_TX_POLARITY_LSB 0 +#define GTHE4_CH_TX_POLARITY_MASK BIT_MASK(GTHE4_CH_TX_POLARITY_MSB, GTHE4_CH_TX_POLARITY_LSB) +#define GTHE4_CH_TX_ELECIDLE_ADDR 0x10010 +#define GTHE4_CH_TX_ELECIDLE_MSB 1 +#define GTHE4_CH_TX_ELECIDLE_LSB 1 +#define GTHE4_CH_TX_ELECIDLE_MASK BIT_MASK(GTHE4_CH_TX_ELECIDLE_MSB, GTHE4_CH_TX_ELECIDLE_LSB) +#define GTHE4_CH_TX_INHIBIT_ADDR 0x10010 +#define GTHE4_CH_TX_INHIBIT_MSB 2 +#define GTHE4_CH_TX_INHIBIT_LSB 2 +#define GTHE4_CH_TX_INHIBIT_MASK BIT_MASK(GTHE4_CH_TX_INHIBIT_MSB, GTHE4_CH_TX_INHIBIT_LSB) +#define GTHE4_CH_TX_DIFFCTRL_ADDR 0x10011 +#define GTHE4_CH_TX_DIFFCTRL_MSB 4 +#define GTHE4_CH_TX_DIFFCTRL_LSB 0 +#define GTHE4_CH_TX_DIFFCTRL_MASK BIT_MASK(GTHE4_CH_TX_DIFFCTRL_MSB, GTHE4_CH_TX_DIFFCTRL_LSB) +#define GTHE4_CH_TX_MAINCURSOR_ADDR 0x10012 +#define GTHE4_CH_TX_MAINCURSOR_MSB 6 +#define GTHE4_CH_TX_MAINCURSOR_LSB 0 +#define GTHE4_CH_TX_MAINCURSOR_MASK BIT_MASK(GTHE4_CH_TX_MAINCURSOR_MSB, GTHE4_CH_TX_MAINCURSOR_LSB) +#define GTHE4_CH_TX_PRECURSOR_ADDR 0x10013 +#define GTHE4_CH_TX_PRECURSOR_MSB 4 +#define GTHE4_CH_TX_PRECURSOR_LSB 0 +#define GTHE4_CH_TX_PRECURSOR_MASK BIT_MASK(GTHE4_CH_TX_PRECURSOR_MSB, GTHE4_CH_TX_PRECURSOR_LSB) +#define GTHE4_CH_TX_POSTCURSOR_ADDR 0x10014 +#define GTHE4_CH_TX_POSTCURSOR_MSB 4 +#define GTHE4_CH_TX_POSTCURSOR_LSB 0 +#define GTHE4_CH_TX_POSTCURSOR_MASK BIT_MASK(GTHE4_CH_TX_POSTCURSOR_MSB, GTHE4_CH_TX_POSTCURSOR_LSB) +#define GTHE4_CH_TX_PRBS_SEL_ADDR 0x10040 +#define GTHE4_CH_TX_PRBS_SEL_MSB 3 +#define GTHE4_CH_TX_PRBS_SEL_LSB 0 +#define GTHE4_CH_TX_PRBS_SEL_MASK BIT_MASK(GTHE4_CH_TX_PRBS_SEL_MSB, GTHE4_CH_TX_PRBS_SEL_LSB) +#define GTHE4_CH_TX_PRBS_FORCERR_ADDR 0x10040 +#define GTHE4_CH_TX_PRBS_FORCERR_MSB 15 +#define GTHE4_CH_TX_PRBS_FORCERR_LSB 0 +#define GTHE4_CH_TX_PRBS_FORCERR_MASK BIT_MASK(GTHE4_CH_TX_PRBS_FORCERR_MSB, GTHE4_CH_TX_PRBS_FORCERR_LSB) +#define GTHE4_CH_RX_RESET_ADDR 0x11000 +#define GTHE4_CH_RX_RESET_MSB 0 +#define GTHE4_CH_RX_RESET_LSB 0 +#define GTHE4_CH_RX_RESET_MASK BIT_MASK(GTHE4_CH_RX_RESET_MSB, GTHE4_CH_RX_RESET_LSB) +#define GTHE4_CH_RX_PMA_RESET_ADDR 0x11000 +#define GTHE4_CH_RX_PMA_RESET_MSB 1 +#define GTHE4_CH_RX_PMA_RESET_LSB 1 +#define GTHE4_CH_RX_PMA_RESET_MASK BIT_MASK(GTHE4_CH_RX_PMA_RESET_MSB, GTHE4_CH_RX_PMA_RESET_LSB) +#define GTHE4_CH_RX_PCS_RESET_ADDR 0x11000 +#define GTHE4_CH_RX_PCS_RESET_MSB 2 +#define GTHE4_CH_RX_PCS_RESET_LSB 2 +#define GTHE4_CH_RX_PCS_RESET_MASK BIT_MASK(GTHE4_CH_RX_PCS_RESET_MSB, GTHE4_CH_RX_PCS_RESET_LSB) +#define GTHE4_CH_RX_DFE_LPM_RESET_ADDR 0x11000 +#define GTHE4_CH_RX_DFE_LPM_RESET_MSB 3 +#define GTHE4_CH_RX_DFE_LPM_RESET_LSB 3 +#define GTHE4_CH_RX_DFE_LPM_RESET_MASK BIT_MASK(GTHE4_CH_RX_DFE_LPM_RESET_MSB, GTHE4_CH_RX_DFE_LPM_RESET_LSB) +#define GTHE4_CH_EYESCAN_RESET_ADDR 0x11000 +#define GTHE4_CH_EYESCAN_RESET_MSB 4 +#define GTHE4_CH_EYESCAN_RESET_LSB 4 +#define GTHE4_CH_EYESCAN_RESET_MASK BIT_MASK(GTHE4_CH_EYESCAN_RESET_MSB, GTHE4_CH_EYESCAN_RESET_LSB) +#define GTHE4_CH_RX_RESET_DONE_ADDR 0x11000 +#define GTHE4_CH_RX_RESET_DONE_MSB 8 +#define GTHE4_CH_RX_RESET_DONE_LSB 8 +#define GTHE4_CH_RX_RESET_DONE_MASK BIT_MASK(GTHE4_CH_RX_RESET_DONE_MSB, GTHE4_CH_RX_RESET_DONE_LSB) +#define GTHE4_CH_RX_GT_RESET_DONE_ADDR 0x11000 +#define GTHE4_CH_RX_GT_RESET_DONE_MSB 9 +#define GTHE4_CH_RX_GT_RESET_DONE_LSB 9 +#define GTHE4_CH_RX_GT_RESET_DONE_MASK BIT_MASK(GTHE4_CH_RX_GT_RESET_DONE_MSB, GTHE4_CH_RX_GT_RESET_DONE_LSB) +#define GTHE4_CH_RX_PMA_RESET_DONE_ADDR 0x11000 +#define GTHE4_CH_RX_PMA_RESET_DONE_MSB 10 +#define GTHE4_CH_RX_PMA_RESET_DONE_LSB 10 +#define GTHE4_CH_RX_PMA_RESET_DONE_MASK BIT_MASK(GTHE4_CH_RX_PMA_RESET_DONE_MSB, GTHE4_CH_RX_PMA_RESET_DONE_LSB) +#define GTHE4_CH_RX_PRGDIV_RESET_DONE_ADDR 0x11000 +#define GTHE4_CH_RX_PRGDIV_RESET_DONE_MSB 11 +#define GTHE4_CH_RX_PRGDIV_RESET_DONE_LSB 11 +#define GTHE4_CH_RX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTHE4_CH_RX_PRGDIV_RESET_DONE_MSB, GTHE4_CH_RX_PRGDIV_RESET_DONE_LSB) +#define GTHE4_CH_RX_USRCLK_ACT_ADDR 0x11000 +#define GTHE4_CH_RX_USRCLK_ACT_MSB 12 +#define GTHE4_CH_RX_USRCLK_ACT_LSB 12 +#define GTHE4_CH_RX_USRCLK_ACT_MASK BIT_MASK(GTHE4_CH_RX_USRCLK_ACT_MSB, GTHE4_CH_RX_USRCLK_ACT_LSB) +#define GTHE4_CH_RX_PD_ADDR 0x11001 +#define GTHE4_CH_RX_PD_MSB 0 +#define GTHE4_CH_RX_PD_LSB 0 +#define GTHE4_CH_RX_PD_MASK BIT_MASK(GTHE4_CH_RX_PD_MSB, GTHE4_CH_RX_PD_LSB) +#define GTHE4_CH_RX_QPLL_SEL_ADDR 0x11001 +#define GTHE4_CH_RX_QPLL_SEL_MSB 1 +#define GTHE4_CH_RX_QPLL_SEL_LSB 1 +#define GTHE4_CH_RX_QPLL_SEL_MASK BIT_MASK(GTHE4_CH_RX_QPLL_SEL_MSB, GTHE4_CH_RX_QPLL_SEL_LSB) +#define GTHE4_CH_LOOPBACK_ADDR 0x11002 +#define GTHE4_CH_LOOPBACK_MSB 2 +#define GTHE4_CH_LOOPBACK_LSB 0 +#define GTHE4_CH_LOOPBACK_MASK BIT_MASK(GTHE4_CH_LOOPBACK_MSB, GTHE4_CH_LOOPBACK_LSB) +#define GTHE4_CH_RX_POLARITY_ADDR 0x11010 +#define GTHE4_CH_RX_POLARITY_MSB 0 +#define GTHE4_CH_RX_POLARITY_LSB 0 +#define GTHE4_CH_RX_POLARITY_MASK BIT_MASK(GTHE4_CH_RX_POLARITY_MSB, GTHE4_CH_RX_POLARITY_LSB) +#define GTHE4_CH_RX_CDR_HOLD_ADDR 0x11020 +#define GTHE4_CH_RX_CDR_HOLD_MSB 0 +#define GTHE4_CH_RX_CDR_HOLD_LSB 0 +#define GTHE4_CH_RX_CDR_HOLD_MASK BIT_MASK(GTHE4_CH_RX_CDR_HOLD_MSB, GTHE4_CH_RX_CDR_HOLD_LSB) +#define GTHE4_CH_RX_CDR_LOCK_ADDR 0x11020 +#define GTHE4_CH_RX_CDR_LOCK_MSB 8 +#define GTHE4_CH_RX_CDR_LOCK_LSB 8 +#define GTHE4_CH_RX_CDR_LOCK_MASK BIT_MASK(GTHE4_CH_RX_CDR_LOCK_MSB, GTHE4_CH_RX_CDR_LOCK_LSB) +#define GTHE4_CH_RX_LPM_EN_ADDR 0x11024 +#define GTHE4_CH_RX_LPM_EN_MSB 0 +#define GTHE4_CH_RX_LPM_EN_LSB 0 +#define GTHE4_CH_RX_LPM_EN_MASK BIT_MASK(GTHE4_CH_RX_LPM_EN_MSB, GTHE4_CH_RX_LPM_EN_LSB) +#define GTHE4_CH_RX_DMONITOR_ADDR 0x11028 +#define GTHE4_CH_RX_DMONITOR_MSB 7 +#define GTHE4_CH_RX_DMONITOR_LSB 0 +#define GTHE4_CH_RX_DMONITOR_MASK BIT_MASK(GTHE4_CH_RX_DMONITOR_MSB, GTHE4_CH_RX_DMONITOR_LSB) +#define GTHE4_CH_RX_PRBS_SEL_ADDR 0x11040 +#define GTHE4_CH_RX_PRBS_SEL_MSB 3 +#define GTHE4_CH_RX_PRBS_SEL_LSB 0 +#define GTHE4_CH_RX_PRBS_SEL_MASK BIT_MASK(GTHE4_CH_RX_PRBS_SEL_MSB, GTHE4_CH_RX_PRBS_SEL_LSB) +#define GTHE4_CH_RX_PRBS_CNT_RESET_ADDR 0x11041 +#define GTHE4_CH_RX_PRBS_CNT_RESET_MSB 0 +#define GTHE4_CH_RX_PRBS_CNT_RESET_LSB 0 +#define GTHE4_CH_RX_PRBS_CNT_RESET_MASK BIT_MASK(GTHE4_CH_RX_PRBS_CNT_RESET_MSB, GTHE4_CH_RX_PRBS_CNT_RESET_LSB) +#define GTHE4_CH_RX_PRBS_LOCKED_ADDR 0x11041 +#define GTHE4_CH_RX_PRBS_LOCKED_MSB 8 +#define GTHE4_CH_RX_PRBS_LOCKED_LSB 8 +#define GTHE4_CH_RX_PRBS_LOCKED_MASK BIT_MASK(GTHE4_CH_RX_PRBS_LOCKED_MSB, GTHE4_CH_RX_PRBS_LOCKED_LSB) +#define GTHE4_CH_RX_PRBS_ERROR_ADDR 0x11041 +#define GTHE4_CH_RX_PRBS_ERROR_MSB 9 +#define GTHE4_CH_RX_PRBS_ERROR_LSB 9 +#define GTHE4_CH_RX_PRBS_ERROR_MASK BIT_MASK(GTHE4_CH_RX_PRBS_ERROR_MSB, GTHE4_CH_RX_PRBS_ERROR_LSB) + + +def_gt_pll_masked_reg_rw16(gthe4, qpll0_reset, GTHE4_COM_QPLL0_RESET_ADDR, GTHE4_COM_QPLL0_RESET_MASK, GTHE4_COM_QPLL0_RESET_LSB); +int gthe4_pll_qpll0_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gthe4, qpll0_lock, GTHE4_COM_QPLL0_LOCK_ADDR, GTHE4_COM_QPLL0_LOCK_MASK, GTHE4_COM_QPLL0_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_pd, GTHE4_COM_QPLL0_PD_ADDR, GTHE4_COM_QPLL0_PD_MASK, GTHE4_COM_QPLL0_PD_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_reset, GTHE4_COM_QPLL1_RESET_ADDR, GTHE4_COM_QPLL1_RESET_MASK, GTHE4_COM_QPLL1_RESET_LSB); +int gthe4_pll_qpll1_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gthe4, qpll1_lock, GTHE4_COM_QPLL1_LOCK_ADDR, GTHE4_COM_QPLL1_LOCK_MASK, GTHE4_COM_QPLL1_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_pd, GTHE4_COM_QPLL1_PD_ADDR, GTHE4_COM_QPLL1_PD_MASK, GTHE4_COM_QPLL1_PD_LSB); + +def_gt_ch_masked_reg_rw16(gthe4, tx_reset, GTHE4_CH_TX_RESET_ADDR, GTHE4_CH_TX_RESET_MASK, GTHE4_CH_TX_RESET_LSB); +int gthe4_ch_tx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe4, tx_pma_reset, GTHE4_CH_TX_PMA_RESET_ADDR, GTHE4_CH_TX_PMA_RESET_MASK, GTHE4_CH_TX_PMA_RESET_LSB); +int gthe4_ch_tx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe4, tx_pcs_reset, GTHE4_CH_TX_PCS_RESET_ADDR, GTHE4_CH_TX_PCS_RESET_MASK, GTHE4_CH_TX_PCS_RESET_LSB); +int gthe4_ch_tx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gthe4, tx_reset_done, GTHE4_CH_TX_RESET_DONE_ADDR, GTHE4_CH_TX_RESET_DONE_MASK, GTHE4_CH_TX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, tx_gt_reset_done, GTHE4_CH_TX_GT_RESET_DONE_ADDR, GTHE4_CH_TX_GT_RESET_DONE_MASK, GTHE4_CH_TX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, tx_pma_reset_done, GTHE4_CH_TX_PMA_RESET_DONE_ADDR, GTHE4_CH_TX_PMA_RESET_DONE_MASK, GTHE4_CH_TX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, tx_prgdiv_reset_done, GTHE4_CH_TX_PRGDIV_RESET_DONE_ADDR, GTHE4_CH_TX_PRGDIV_RESET_DONE_MASK, GTHE4_CH_TX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, tx_usrclk_act, GTHE4_CH_TX_USRCLK_ACT_ADDR, GTHE4_CH_TX_USRCLK_ACT_MASK, GTHE4_CH_TX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_pd, GTHE4_CH_TX_PD_ADDR, GTHE4_CH_TX_PD_MASK, GTHE4_CH_TX_PD_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_qpll_sel, GTHE4_CH_TX_QPLL_SEL_ADDR, GTHE4_CH_TX_QPLL_SEL_MASK, GTHE4_CH_TX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_polarity, GTHE4_CH_TX_POLARITY_ADDR, GTHE4_CH_TX_POLARITY_MASK, GTHE4_CH_TX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_elecidle, GTHE4_CH_TX_ELECIDLE_ADDR, GTHE4_CH_TX_ELECIDLE_MASK, GTHE4_CH_TX_ELECIDLE_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_inhibit, GTHE4_CH_TX_INHIBIT_ADDR, GTHE4_CH_TX_INHIBIT_MASK, GTHE4_CH_TX_INHIBIT_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_diffctrl, GTHE4_CH_TX_DIFFCTRL_ADDR, GTHE4_CH_TX_DIFFCTRL_MASK, GTHE4_CH_TX_DIFFCTRL_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_maincursor, GTHE4_CH_TX_MAINCURSOR_ADDR, GTHE4_CH_TX_MAINCURSOR_MASK, GTHE4_CH_TX_MAINCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_precursor, GTHE4_CH_TX_PRECURSOR_ADDR, GTHE4_CH_TX_PRECURSOR_MASK, GTHE4_CH_TX_PRECURSOR_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_postcursor, GTHE4_CH_TX_POSTCURSOR_ADDR, GTHE4_CH_TX_POSTCURSOR_MASK, GTHE4_CH_TX_POSTCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_prbs_sel, GTHE4_CH_TX_PRBS_SEL_ADDR, GTHE4_CH_TX_PRBS_SEL_MASK, GTHE4_CH_TX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe4, tx_prbs_forcerr, GTHE4_CH_TX_PRBS_FORCERR_ADDR, GTHE4_CH_TX_PRBS_FORCERR_MASK, GTHE4_CH_TX_PRBS_FORCERR_LSB); + +def_gt_ch_masked_reg_rw16(gthe4, rx_reset, GTHE4_CH_RX_RESET_ADDR, GTHE4_CH_RX_RESET_MASK, GTHE4_CH_RX_RESET_LSB); +int gthe4_ch_rx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe4, rx_pma_reset, GTHE4_CH_RX_PMA_RESET_ADDR, GTHE4_CH_RX_PMA_RESET_MASK, GTHE4_CH_RX_PMA_RESET_LSB); +int gthe4_ch_rx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe4, rx_pcs_reset, GTHE4_CH_RX_PCS_RESET_ADDR, GTHE4_CH_RX_PCS_RESET_MASK, GTHE4_CH_RX_PCS_RESET_LSB); +int gthe4_ch_rx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe4, rx_dfe_lpm_reset, GTHE4_CH_RX_DFE_LPM_RESET_ADDR, GTHE4_CH_RX_DFE_LPM_RESET_MASK, GTHE4_CH_RX_DFE_LPM_RESET_LSB); +int gthe4_ch_rx_dfe_lpm_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gthe4, eyescan_reset, GTHE4_CH_EYESCAN_RESET_ADDR, GTHE4_CH_EYESCAN_RESET_MASK, GTHE4_CH_EYESCAN_RESET_LSB); +int gthe4_ch_eyescan_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gthe4, rx_reset_done, GTHE4_CH_RX_RESET_DONE_ADDR, GTHE4_CH_RX_RESET_DONE_MASK, GTHE4_CH_RX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_gt_reset_done, GTHE4_CH_RX_GT_RESET_DONE_ADDR, GTHE4_CH_RX_GT_RESET_DONE_MASK, GTHE4_CH_RX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_pma_reset_done, GTHE4_CH_RX_PMA_RESET_DONE_ADDR, GTHE4_CH_RX_PMA_RESET_DONE_MASK, GTHE4_CH_RX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_prgdiv_reset_done, GTHE4_CH_RX_PRGDIV_RESET_DONE_ADDR, GTHE4_CH_RX_PRGDIV_RESET_DONE_MASK, GTHE4_CH_RX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_usrclk_act, GTHE4_CH_RX_USRCLK_ACT_ADDR, GTHE4_CH_RX_USRCLK_ACT_MASK, GTHE4_CH_RX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_pd, GTHE4_CH_RX_PD_ADDR, GTHE4_CH_RX_PD_MASK, GTHE4_CH_RX_PD_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_qpll_sel, GTHE4_CH_RX_QPLL_SEL_ADDR, GTHE4_CH_RX_QPLL_SEL_MASK, GTHE4_CH_RX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe4, loopback, GTHE4_CH_LOOPBACK_ADDR, GTHE4_CH_LOOPBACK_MASK, GTHE4_CH_LOOPBACK_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_polarity, GTHE4_CH_RX_POLARITY_ADDR, GTHE4_CH_RX_POLARITY_MASK, GTHE4_CH_RX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_cdr_hold, GTHE4_CH_RX_CDR_HOLD_ADDR, GTHE4_CH_RX_CDR_HOLD_MASK, GTHE4_CH_RX_CDR_HOLD_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_cdr_lock, GTHE4_CH_RX_CDR_LOCK_ADDR, GTHE4_CH_RX_CDR_LOCK_MASK, GTHE4_CH_RX_CDR_LOCK_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_lpm_en, GTHE4_CH_RX_LPM_EN_ADDR, GTHE4_CH_RX_LPM_EN_MASK, GTHE4_CH_RX_LPM_EN_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_dmonitor, GTHE4_CH_RX_DMONITOR_ADDR, GTHE4_CH_RX_DMONITOR_MASK, GTHE4_CH_RX_DMONITOR_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_prbs_sel, GTHE4_CH_RX_PRBS_SEL_ADDR, GTHE4_CH_RX_PRBS_SEL_MASK, GTHE4_CH_RX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_prbs_cnt_reset, GTHE4_CH_RX_PRBS_CNT_RESET_ADDR, GTHE4_CH_RX_PRBS_CNT_RESET_MASK, GTHE4_CH_RX_PRBS_CNT_RESET_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_prbs_locked, GTHE4_CH_RX_PRBS_LOCKED_ADDR, GTHE4_CH_RX_PRBS_LOCKED_MASK, GTHE4_CH_RX_PRBS_LOCKED_LSB); +def_gt_ch_masked_reg_read16(gthe4, rx_prbs_error, GTHE4_CH_RX_PRBS_ERROR_ADDR, GTHE4_CH_RX_PRBS_ERROR_MASK, GTHE4_CH_RX_PRBS_ERROR_LSB); + +// common +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cfg0, GTHE4_COM_QPLL0_CFG0_ADDR, GTHE4_COM_QPLL0_CFG0_MASK, GTHE4_COM_QPLL0_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, common_cfg0, GTHE4_COM_COMMON_CFG0_ADDR, GTHE4_COM_COMMON_CFG0_MASK, GTHE4_COM_COMMON_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, ppf0_cfg, GTHE4_COM_PPF0_CFG_ADDR, GTHE4_COM_PPF0_CFG_MASK, GTHE4_COM_PPF0_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0clkout_rate, GTHE4_COM_QPLL0CLKOUT_RATE_ADDR, GTHE4_COM_QPLL0CLKOUT_RATE_MASK, GTHE4_COM_QPLL0CLKOUT_RATE_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cfg1, GTHE4_COM_QPLL0_CFG1_ADDR, GTHE4_COM_QPLL0_CFG1_MASK, GTHE4_COM_QPLL0_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cfg2, GTHE4_COM_QPLL0_CFG2_ADDR, GTHE4_COM_QPLL0_CFG2_MASK, GTHE4_COM_QPLL0_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_lock_cfg, GTHE4_COM_QPLL0_LOCK_CFG_ADDR, GTHE4_COM_QPLL0_LOCK_CFG_MASK, GTHE4_COM_QPLL0_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_init_cfg0, GTHE4_COM_QPLL0_INIT_CFG0_ADDR, GTHE4_COM_QPLL0_INIT_CFG0_MASK, GTHE4_COM_QPLL0_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_init_cfg1, GTHE4_COM_QPLL0_INIT_CFG1_ADDR, GTHE4_COM_QPLL0_INIT_CFG1_MASK, GTHE4_COM_QPLL0_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_fbdiv, GTHE4_COM_QPLL0_FBDIV_ADDR, GTHE4_COM_QPLL0_FBDIV_MASK, GTHE4_COM_QPLL0_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cfg3, GTHE4_COM_QPLL0_CFG3_ADDR, GTHE4_COM_QPLL0_CFG3_MASK, GTHE4_COM_QPLL0_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cp, GTHE4_COM_QPLL0_CP_ADDR, GTHE4_COM_QPLL0_CP_MASK, GTHE4_COM_QPLL0_CP_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_refclk_div, GTHE4_COM_QPLL0_REFCLK_DIV_ADDR, GTHE4_COM_QPLL0_REFCLK_DIV_MASK, GTHE4_COM_QPLL0_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_lpf, GTHE4_COM_QPLL0_LPF_ADDR, GTHE4_COM_QPLL0_LPF_MASK, GTHE4_COM_QPLL0_LPF_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cfg1_g3, GTHE4_COM_QPLL0_CFG1_G3_ADDR, GTHE4_COM_QPLL0_CFG1_G3_MASK, GTHE4_COM_QPLL0_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cfg2_g3, GTHE4_COM_QPLL0_CFG2_G3_ADDR, GTHE4_COM_QPLL0_CFG2_G3_MASK, GTHE4_COM_QPLL0_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_lpf_g3, GTHE4_COM_QPLL0_LPF_G3_ADDR, GTHE4_COM_QPLL0_LPF_G3_MASK, GTHE4_COM_QPLL0_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_lock_cfg_g3, GTHE4_COM_QPLL0_LOCK_CFG_G3_ADDR, GTHE4_COM_QPLL0_LOCK_CFG_G3_MASK, GTHE4_COM_QPLL0_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, rsvd_attr0, GTHE4_COM_RSVD_ATTR0_ADDR, GTHE4_COM_RSVD_ATTR0_MASK, GTHE4_COM_RSVD_ATTR0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_fbdiv_g3, GTHE4_COM_QPLL0_FBDIV_G3_ADDR, GTHE4_COM_QPLL0_FBDIV_G3_MASK, GTHE4_COM_QPLL0_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_rate_sw_use_drp, GTHE4_COM_QPLL0_RATE_SW_USE_DRP_ADDR, GTHE4_COM_QPLL0_RATE_SW_USE_DRP_MASK, GTHE4_COM_QPLL0_RATE_SW_USE_DRP_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_pci_en, GTHE4_COM_QPLL0_PCI_EN_ADDR, GTHE4_COM_QPLL0_PCI_EN_MASK, GTHE4_COM_QPLL0_PCI_EN_LSB); +def_gt_pll_masked_reg_rw16(gthe4, rxrecclkout0_sel, GTHE4_COM_RXRECCLKOUT0_SEL_ADDR, GTHE4_COM_RXRECCLKOUT0_SEL_MASK, GTHE4_COM_RXRECCLKOUT0_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_sdm_cfg0, GTHE4_COM_QPLL0_SDM_CFG0_ADDR, GTHE4_COM_QPLL0_SDM_CFG0_MASK, GTHE4_COM_QPLL0_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_sdm_cfg1, GTHE4_COM_QPLL0_SDM_CFG1_ADDR, GTHE4_COM_QPLL0_SDM_CFG1_MASK, GTHE4_COM_QPLL0_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, sdm0initseed0_0, GTHE4_COM_SDM0INITSEED0_0_ADDR, GTHE4_COM_SDM0INITSEED0_0_MASK, GTHE4_COM_SDM0INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, sdm0initseed0_1, GTHE4_COM_SDM0INITSEED0_1_ADDR, GTHE4_COM_SDM0INITSEED0_1_MASK, GTHE4_COM_SDM0INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_sdm_cfg2, GTHE4_COM_QPLL0_SDM_CFG2_ADDR, GTHE4_COM_QPLL0_SDM_CFG2_MASK, GTHE4_COM_QPLL0_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cp_g3, GTHE4_COM_QPLL0_CP_G3_ADDR, GTHE4_COM_QPLL0_CP_G3_MASK, GTHE4_COM_QPLL0_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, aen_qpll0_fbdiv, GTHE4_COM_AEN_QPLL0_FBDIV_ADDR, GTHE4_COM_AEN_QPLL0_FBDIV_MASK, GTHE4_COM_AEN_QPLL0_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gthe4, aen_sdm0toggle, GTHE4_COM_AEN_SDM0TOGGLE_ADDR, GTHE4_COM_AEN_SDM0TOGGLE_MASK, GTHE4_COM_AEN_SDM0TOGGLE_LSB); +def_gt_pll_masked_reg_rw16(gthe4, a_sdm0toggle, GTHE4_COM_A_SDM0TOGGLE_ADDR, GTHE4_COM_A_SDM0TOGGLE_MASK, GTHE4_COM_A_SDM0TOGGLE_LSB); +def_gt_pll_masked_reg_rw16(gthe4, rsvd_attr1, GTHE4_COM_RSVD_ATTR1_ADDR, GTHE4_COM_RSVD_ATTR1_MASK, GTHE4_COM_RSVD_ATTR1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll0_cfg4, GTHE4_COM_QPLL0_CFG4_ADDR, GTHE4_COM_QPLL0_CFG4_MASK, GTHE4_COM_QPLL0_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gthe4, bias_cfg0, GTHE4_COM_BIAS_CFG0_ADDR, GTHE4_COM_BIAS_CFG0_MASK, GTHE4_COM_BIAS_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, bias_cfg1, GTHE4_COM_BIAS_CFG1_ADDR, GTHE4_COM_BIAS_CFG1_MASK, GTHE4_COM_BIAS_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, bias_cfg2, GTHE4_COM_BIAS_CFG2_ADDR, GTHE4_COM_BIAS_CFG2_MASK, GTHE4_COM_BIAS_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe4, bias_cfg3, GTHE4_COM_BIAS_CFG3_ADDR, GTHE4_COM_BIAS_CFG3_MASK, GTHE4_COM_BIAS_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, bias_cfg4, GTHE4_COM_BIAS_CFG4_ADDR, GTHE4_COM_BIAS_CFG4_MASK, GTHE4_COM_BIAS_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cfg0, GTHE4_COM_QPLL1_CFG0_ADDR, GTHE4_COM_QPLL1_CFG0_MASK, GTHE4_COM_QPLL1_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, common_cfg1, GTHE4_COM_COMMON_CFG1_ADDR, GTHE4_COM_COMMON_CFG1_MASK, GTHE4_COM_COMMON_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, por_cfg, GTHE4_COM_POR_CFG_ADDR, GTHE4_COM_POR_CFG_MASK, GTHE4_COM_POR_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe4, ppf1_cfg, GTHE4_COM_PPF1_CFG_ADDR, GTHE4_COM_PPF1_CFG_MASK, GTHE4_COM_PPF1_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1clkout_rate, GTHE4_COM_QPLL1CLKOUT_RATE_ADDR, GTHE4_COM_QPLL1CLKOUT_RATE_MASK, GTHE4_COM_QPLL1CLKOUT_RATE_LSB); +def_gt_pll_masked_reg_rw16(gthe4, bias_cfg_rsvd, GTHE4_COM_BIAS_CFG_RSVD_ADDR, GTHE4_COM_BIAS_CFG_RSVD_MASK, GTHE4_COM_BIAS_CFG_RSVD_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cfg1, GTHE4_COM_QPLL1_CFG1_ADDR, GTHE4_COM_QPLL1_CFG1_MASK, GTHE4_COM_QPLL1_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cfg2, GTHE4_COM_QPLL1_CFG2_ADDR, GTHE4_COM_QPLL1_CFG2_MASK, GTHE4_COM_QPLL1_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_lock_cfg, GTHE4_COM_QPLL1_LOCK_CFG_ADDR, GTHE4_COM_QPLL1_LOCK_CFG_MASK, GTHE4_COM_QPLL1_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_init_cfg0, GTHE4_COM_QPLL1_INIT_CFG0_ADDR, GTHE4_COM_QPLL1_INIT_CFG0_MASK, GTHE4_COM_QPLL1_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_init_cfg1, GTHE4_COM_QPLL1_INIT_CFG1_ADDR, GTHE4_COM_QPLL1_INIT_CFG1_MASK, GTHE4_COM_QPLL1_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_fbdiv, GTHE4_COM_QPLL1_FBDIV_ADDR, GTHE4_COM_QPLL1_FBDIV_MASK, GTHE4_COM_QPLL1_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cfg3, GTHE4_COM_QPLL1_CFG3_ADDR, GTHE4_COM_QPLL1_CFG3_MASK, GTHE4_COM_QPLL1_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cp, GTHE4_COM_QPLL1_CP_ADDR, GTHE4_COM_QPLL1_CP_MASK, GTHE4_COM_QPLL1_CP_LSB); +def_gt_pll_masked_reg_rw16(gthe4, sarc_sel, GTHE4_COM_SARC_SEL_ADDR, GTHE4_COM_SARC_SEL_MASK, GTHE4_COM_SARC_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe4, sarc_enb, GTHE4_COM_SARC_ENB_ADDR, GTHE4_COM_SARC_ENB_MASK, GTHE4_COM_SARC_ENB_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_refclk_div, GTHE4_COM_QPLL1_REFCLK_DIV_ADDR, GTHE4_COM_QPLL1_REFCLK_DIV_MASK, GTHE4_COM_QPLL1_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_lpf, GTHE4_COM_QPLL1_LPF_ADDR, GTHE4_COM_QPLL1_LPF_MASK, GTHE4_COM_QPLL1_LPF_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cfg1_g3, GTHE4_COM_QPLL1_CFG1_G3_ADDR, GTHE4_COM_QPLL1_CFG1_G3_MASK, GTHE4_COM_QPLL1_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cfg2_g3, GTHE4_COM_QPLL1_CFG2_G3_ADDR, GTHE4_COM_QPLL1_CFG2_G3_MASK, GTHE4_COM_QPLL1_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_lpf_g3, GTHE4_COM_QPLL1_LPF_G3_ADDR, GTHE4_COM_QPLL1_LPF_G3_MASK, GTHE4_COM_QPLL1_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_lock_cfg_g3, GTHE4_COM_QPLL1_LOCK_CFG_G3_ADDR, GTHE4_COM_QPLL1_LOCK_CFG_G3_MASK, GTHE4_COM_QPLL1_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, rsvd_attr2, GTHE4_COM_RSVD_ATTR2_ADDR, GTHE4_COM_RSVD_ATTR2_MASK, GTHE4_COM_RSVD_ATTR2_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_fbdiv_g3, GTHE4_COM_QPLL1_FBDIV_G3_ADDR, GTHE4_COM_QPLL1_FBDIV_G3_MASK, GTHE4_COM_QPLL1_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_rate_sw_use_drp, GTHE4_COM_QPLL1_RATE_SW_USE_DRP_ADDR, GTHE4_COM_QPLL1_RATE_SW_USE_DRP_MASK, GTHE4_COM_QPLL1_RATE_SW_USE_DRP_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_pci_en, GTHE4_COM_QPLL1_PCI_EN_ADDR, GTHE4_COM_QPLL1_PCI_EN_MASK, GTHE4_COM_QPLL1_PCI_EN_LSB); +def_gt_pll_masked_reg_rw16(gthe4, rxrecclkout1_sel, GTHE4_COM_RXRECCLKOUT1_SEL_ADDR, GTHE4_COM_RXRECCLKOUT1_SEL_MASK, GTHE4_COM_RXRECCLKOUT1_SEL_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_sdm_cfg0, GTHE4_COM_QPLL1_SDM_CFG0_ADDR, GTHE4_COM_QPLL1_SDM_CFG0_MASK, GTHE4_COM_QPLL1_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_sdm_cfg1, GTHE4_COM_QPLL1_SDM_CFG1_ADDR, GTHE4_COM_QPLL1_SDM_CFG1_MASK, GTHE4_COM_QPLL1_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, sdm1initseed0_0, GTHE4_COM_SDM1INITSEED0_0_ADDR, GTHE4_COM_SDM1INITSEED0_0_MASK, GTHE4_COM_SDM1INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gthe4, sdm1initseed0_1, GTHE4_COM_SDM1INITSEED0_1_ADDR, GTHE4_COM_SDM1INITSEED0_1_MASK, GTHE4_COM_SDM1INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_sdm_cfg2, GTHE4_COM_QPLL1_SDM_CFG2_ADDR, GTHE4_COM_QPLL1_SDM_CFG2_MASK, GTHE4_COM_QPLL1_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cp_g3, GTHE4_COM_QPLL1_CP_G3_ADDR, GTHE4_COM_QPLL1_CP_G3_MASK, GTHE4_COM_QPLL1_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, a_sdm1data_low, GTHE4_COM_A_SDM1DATA_LOW_ADDR, GTHE4_COM_A_SDM1DATA_LOW_MASK, GTHE4_COM_A_SDM1DATA_LOW_LSB); +def_gt_pll_masked_reg_rw16(gthe4, aen_qpll1_fbdiv, GTHE4_COM_AEN_QPLL1_FBDIV_ADDR, GTHE4_COM_AEN_QPLL1_FBDIV_MASK, GTHE4_COM_AEN_QPLL1_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gthe4, aen_sdm1toggle, GTHE4_COM_AEN_SDM1TOGGLE_ADDR, GTHE4_COM_AEN_SDM1TOGGLE_MASK, GTHE4_COM_AEN_SDM1TOGGLE_LSB); +def_gt_pll_masked_reg_rw16(gthe4, a_sdm1toggle, GTHE4_COM_A_SDM1TOGGLE_ADDR, GTHE4_COM_A_SDM1TOGGLE_MASK, GTHE4_COM_A_SDM1TOGGLE_LSB); +def_gt_pll_masked_reg_rw16(gthe4, a_sdm1data_high, GTHE4_COM_A_SDM1DATA_HIGH_ADDR, GTHE4_COM_A_SDM1DATA_HIGH_MASK, GTHE4_COM_A_SDM1DATA_HIGH_LSB); +def_gt_pll_masked_reg_rw16(gthe4, rsvd_attr3, GTHE4_COM_RSVD_ATTR3_ADDR, GTHE4_COM_RSVD_ATTR3_MASK, GTHE4_COM_RSVD_ATTR3_LSB); +def_gt_pll_masked_reg_rw16(gthe4, qpll1_cfg4, GTHE4_COM_QPLL1_CFG4_ADDR, GTHE4_COM_QPLL1_CFG4_MASK, GTHE4_COM_QPLL1_CFG4_LSB); + +// RX +def_gt_ch_masked_reg_rw16(gthe4, rx_data_width_raw, GTHE4_CH_RX_DATA_WIDTH_ADDR, GTHE4_CH_RX_DATA_WIDTH_MASK, GTHE4_CH_RX_DATA_WIDTH_LSB); +int gthe4_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gthe4, rx_int_data_width_raw, GTHE4_CH_RX_INT_DATAWIDTH_ADDR, GTHE4_CH_RX_INT_DATAWIDTH_MASK, GTHE4_CH_RX_INT_DATAWIDTH_LSB); +int gthe4_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gthe4, es_prescale, GTHE4_CH_ES_PRESCALE_ADDR, GTHE4_CH_ES_PRESCALE_MASK, GTHE4_CH_ES_PRESCALE_LSB); +def_gt_ch_masked_reg_rw16(gthe4, es_eye_scan_en, GTHE4_CH_ES_EYE_SCAN_EN_ADDR, GTHE4_CH_ES_EYE_SCAN_EN_MASK, GTHE4_CH_ES_EYE_SCAN_EN_LSB); +def_gt_ch_masked_reg_rw16(gthe4, es_errdet_en, GTHE4_CH_ES_ERRDET_EN_ADDR, GTHE4_CH_ES_ERRDET_EN_MASK, GTHE4_CH_ES_ERRDET_EN_LSB); +def_gt_ch_masked_reg_rw16(gthe4, es_control, GTHE4_CH_ES_CONTROL_ADDR, GTHE4_CH_ES_CONTROL_MASK, GTHE4_CH_ES_CONTROL_LSB); + +int gthe4_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask); +int gthe4_ch_set_es_qual_mask_clear(struct gt_ch *ch); + +int gthe4_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask); +int gthe4_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width); + +def_gt_ch_masked_reg_rw16(gthe4, es_horz_offset, GTHE4_CH_ES_HORZ_OFFSET_ADDR, GTHE4_CH_ES_HORZ_OFFSET_MASK, GTHE4_CH_ES_HORZ_OFFSET_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_eyescan_vs_range, GTHE4_CH_RX_EYESCAN_VS_RANGE_ADDR, GTHE4_CH_RX_EYESCAN_VS_RANGE_MASK, GTHE4_CH_RX_EYESCAN_VS_RANGE_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_eyescan_vs_code, GTHE4_CH_RX_EYESCAN_VS_CODE_ADDR, GTHE4_CH_RX_EYESCAN_VS_CODE_MASK, GTHE4_CH_RX_EYESCAN_VS_CODE_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_eyescan_vs_ut_sign, GTHE4_CH_RX_EYESCAN_VS_UT_SIGN_ADDR, GTHE4_CH_RX_EYESCAN_VS_UT_SIGN_MASK, GTHE4_CH_RX_EYESCAN_VS_UT_SIGN_LSB); +def_gt_ch_masked_reg_rw16(gthe4, rx_eyescan_vs_neg_dir, GTHE4_CH_RX_EYESCAN_VS_NEG_DIR_ADDR, GTHE4_CH_RX_EYESCAN_VS_NEG_DIR_MASK, GTHE4_CH_RX_EYESCAN_VS_NEG_DIR_LSB); +def_gt_ch_masked_reg_read16(gthe4, es_error_count, GTHE4_CH_ES_ERROR_COUNT_ADDR, GTHE4_CH_ES_ERROR_COUNT_MASK, GTHE4_CH_ES_ERROR_COUNT_LSB); +def_gt_ch_masked_reg_read16(gthe4, es_sample_count, GTHE4_CH_ES_SAMPLE_COUNT_ADDR, GTHE4_CH_ES_SAMPLE_COUNT_MASK, GTHE4_CH_ES_SAMPLE_COUNT_LSB); +def_gt_ch_masked_reg_read16(gthe4, es_control_status, GTHE4_CH_ES_CONTROL_STATUS_ADDR, GTHE4_CH_ES_CONTROL_STATUS_MASK, GTHE4_CH_ES_CONTROL_STATUS_LSB); + +int gthe4_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val); + +// TX +def_gt_ch_masked_reg_rw16(gthe4, tx_data_width_raw, GTHE4_CH_TX_DATA_WIDTH_ADDR, GTHE4_CH_TX_DATA_WIDTH_MASK, GTHE4_CH_TX_DATA_WIDTH_LSB); +int gthe4_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gthe4, tx_int_data_width_raw, GTHE4_CH_TX_INT_DATAWIDTH_ADDR, GTHE4_CH_TX_INT_DATAWIDTH_MASK, GTHE4_CH_TX_INT_DATAWIDTH_LSB); +int gthe4_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val); + +extern const struct gt_quad_ops gthe4_gt_quad_ops; + +#endif /* XCVR_GTHE4_H */ diff --git a/utils/xcvr_gtye3.c b/utils/xcvr_gtye3.c new file mode 100644 index 000000000..1e4ea396c --- /dev/null +++ b/utils/xcvr_gtye3.c @@ -0,0 +1,813 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include +#include +#include "xcvr_gtye3.h" + +// signals +int gtye3_pll_qpll0_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gtye3_pll_set_qpll0_reset(pll, 1); + + if (ret) + return ret; + + return gtye3_pll_set_qpll0_reset(pll, 0); +} + +int gtye3_pll_qpll1_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gtye3_pll_set_qpll1_reset(pll, 1); + + if (ret) + return ret; + + return gtye3_pll_set_qpll1_reset(pll, 0); +} + +int gtye3_ch_tx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_tx_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_tx_reset(ch, 0); +} + +int gtye3_ch_tx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_tx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_tx_pma_reset(ch, 0); +} + +int gtye3_ch_tx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_tx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_tx_pcs_reset(ch, 0); +} + +int gtye3_ch_rx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_rx_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_rx_reset(ch, 0); +} + +int gtye3_ch_rx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_rx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_rx_pma_reset(ch, 0); +} + +int gtye3_ch_rx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_rx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_rx_pcs_reset(ch, 0); +} + +int gtye3_ch_rx_dfe_lpm_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_rx_dfe_lpm_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_rx_dfe_lpm_reset(ch, 0); +} + +int gtye3_ch_eyescan_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye3_ch_set_eyescan_reset(ch, 1); + + if (ret) + return ret; + + return gtye3_ch_set_eyescan_reset(ch, 0); +} + +// RX +int gtye3_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gtye3_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gtye3_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gtye3_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gtye3_ch_get_rx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gtye3_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_QUAL_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_QUAL_MASK5_ADDR+k, mask[2*k+10] | (mask[2*k+11] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gtye3_ch_set_es_qual_mask_clear(struct gt_ch *ch) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_QUAL_MASK0_ADDR+k, 0xffff); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_QUAL_MASK5_ADDR+k, 0xffff); + if (ret) + return ret; + } + + return 0; +} + +int gtye3_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_SDATA_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_SDATA_MASK5_ADDR+k, mask[2*k+10] | (mask[2*k+11] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gtye3_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + int shift = width - (80 - ((k+1)*16)); + uint32_t mask = 0xffff; + + if (shift < 0) + { + mask = 0xffff; + } + else if (shift > 16) + { + mask = 0x0000; + } + else + { + mask = 0xffff >> shift; + } + + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_SDATA_MASK0_ADDR+k, mask); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE3_CH_ES_SDATA_MASK5_ADDR+k, 0xffff); + if (ret) + return ret; + } + + return 0; +} + +int gtye3_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t v1, v2; + + ret = gt_ch_reg_read(ch, GTYE3_CH_RX_PRBS_ERR_CNT_L_ADDR | (ch->index << 17), &v1); + if (ret) + return ret; + + ret = gt_ch_reg_read(ch, GTYE3_CH_RX_PRBS_ERR_CNT_H_ADDR | (ch->index << 17), &v2); + if (ret) + return ret; + + *val = v1 | (v2 << 16); + return 0; +} + +// TX +int gtye3_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gtye3_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gtye3_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gtye3_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gtye3_ch_get_tx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +struct gtye3_quad_priv { + int qpll0_25g; +}; + +struct gtye3_ch_priv { + uint32_t tx_data_width; + uint32_t tx_int_data_width; + uint32_t rx_data_width; + uint32_t rx_int_data_width; + int dfe_en; + + int prescale; + int h_start; + int h_stop; + int h_step; + int v_range; + int v_start; + int v_stop; + int v_step; + + int h_offset; + int v_offset; + int ut_sign; + int eyescan_running; +}; + +static const struct gt_reg_val gtye3_ch_preset_10g_baser_64_regs[] = { + {GTYE3_CH_CH_HSPMUX_ADDR, GTYE3_CH_CH_HSPMUX_MASK, GTYE3_CH_CH_HSPMUX_LSB, 0x2424}, + {GTYE3_CH_CKCAL1_CFG_3_ADDR, GTYE3_CH_CKCAL1_CFG_3_MASK, GTYE3_CH_CKCAL1_CFG_3_LSB, 0x0000}, + {GTYE3_CH_CKCAL2_CFG_0_ADDR, GTYE3_CH_CKCAL2_CFG_0_MASK, GTYE3_CH_CKCAL2_CFG_0_LSB, 0xC0C0}, + {GTYE3_CH_CKCAL2_CFG_1_ADDR, GTYE3_CH_CKCAL2_CFG_1_MASK, GTYE3_CH_CKCAL2_CFG_1_LSB, 0x80C0}, + {GTYE3_CH_CKCAL_RSVD1_ADDR, GTYE3_CH_CKCAL_RSVD1_MASK, GTYE3_CH_CKCAL_RSVD1_LSB, 0x0400}, + {GTYE3_CH_PMA_RSV0_ADDR, GTYE3_CH_PMA_RSV0_MASK, GTYE3_CH_PMA_RSV0_LSB, 0x2104}, + {GTYE3_CH_PMA_RSV1_ADDR, GTYE3_CH_PMA_RSV1_MASK, GTYE3_CH_PMA_RSV1_LSB, 0x505A}, + {GTYE3_CH_PREIQ_FREQ_BST_ADDR, GTYE3_CH_PREIQ_FREQ_BST_MASK, GTYE3_CH_PREIQ_FREQ_BST_LSB, 0x0000}, + {GTYE3_CH_RXCDR_CFG2_GEN3_ADDR, GTYE3_CH_RXCDR_CFG2_GEN3_MASK, GTYE3_CH_RXCDR_CFG2_GEN3_LSB, 0x0265}, + {GTYE3_CH_RXCDR_CFG2_ADDR, GTYE3_CH_RXCDR_CFG2_MASK, GTYE3_CH_RXCDR_CFG2_LSB, 0x0265}, + {GTYE3_CH_RXPI_CFG_ADDR, GTYE3_CH_RXPI_CFG_MASK, GTYE3_CH_RXPI_CFG_LSB, 0x0202}, + {GTYE3_CH_RX_DFE_KL_LPM_KH_CFG0_ADDR, GTYE3_CH_RX_DFE_KL_LPM_KH_CFG0_MASK, GTYE3_CH_RX_DFE_KL_LPM_KH_CFG0_LSB, 0x0003}, + {GTYE3_CH_RX_DFE_KL_LPM_KL_CFG0_ADDR, GTYE3_CH_RX_DFE_KL_LPM_KL_CFG0_MASK, GTYE3_CH_RX_DFE_KL_LPM_KL_CFG0_LSB, 0x0003}, + {GTYE3_CH_RX_PROGDIV_CFG_ADDR, GTYE3_CH_RX_PROGDIV_CFG_MASK, GTYE3_CH_RX_PROGDIV_CFG_LSB, GTYE3_CH_RX_PROGDIV_CFG_33}, + {GTYE3_CH_RX_PROGDIV_RATE_ADDR, GTYE3_CH_RX_PROGDIV_RATE_MASK, GTYE3_CH_RX_PROGDIV_RATE_LSB, GTYE3_CH_RX_PROGDIV_RATE_FULL}, + {GTYE3_CH_RX_WIDEMODE_CDR_ADDR, GTYE3_CH_RX_WIDEMODE_CDR_MASK, GTYE3_CH_RX_WIDEMODE_CDR_LSB, 0x0002}, + {GTYE3_CH_RX_XMODE_SEL_ADDR, GTYE3_CH_RX_XMODE_SEL_MASK, GTYE3_CH_RX_XMODE_SEL_LSB, 0x0001}, + {GTYE3_CH_TXPI_CFG3_ADDR, GTYE3_CH_TXPI_CFG3_MASK, GTYE3_CH_TXPI_CFG3_LSB, 0x0001}, + {GTYE3_CH_TXPI_CFG4_ADDR, GTYE3_CH_TXPI_CFG4_MASK, GTYE3_CH_TXPI_CFG4_LSB, 0x0001}, + {GTYE3_CH_TX_PI_BIASSET_ADDR, GTYE3_CH_TX_PI_BIASSET_MASK, GTYE3_CH_TX_PI_BIASSET_LSB, 0x0001}, + {GTYE3_CH_TX_PROGDIV_CFG_ADDR, GTYE3_CH_TX_PROGDIV_CFG_MASK, GTYE3_CH_TX_PROGDIV_CFG_LSB, GTYE3_CH_TX_PROGDIV_CFG_33}, + {GTYE3_CH_TX_PROGDIV_RATE_ADDR, GTYE3_CH_TX_PROGDIV_RATE_MASK, GTYE3_CH_TX_PROGDIV_RATE_LSB, GTYE3_CH_TX_PROGDIV_RATE_FULL}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye3_ch_preset_10g_dfe_regs[] = { + {GTYE3_CH_RXDFELPM_KL_CFG1_ADDR, GTYE3_CH_RXDFELPM_KL_CFG1_MASK, GTYE3_CH_RXDFELPM_KL_CFG1_LSB, 0x0002}, + {GTYE3_CH_RXPI_CFG_ADDR, GTYE3_CH_RXPI_CFG_MASK, GTYE3_CH_RXPI_CFG_LSB, 0x0202}, + {GTYE3_CH_RX_DFE_AGC_CFG1_ADDR, GTYE3_CH_RX_DFE_AGC_CFG1_MASK, GTYE3_CH_RX_DFE_AGC_CFG1_LSB, 0x0004}, + {GTYE3_CH_TXPI_CFG0_ADDR, GTYE3_CH_TXPI_CFG0_MASK, GTYE3_CH_TXPI_CFG0_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG1_ADDR, GTYE3_CH_TXPI_CFG1_MASK, GTYE3_CH_TXPI_CFG1_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG2_ADDR, GTYE3_CH_TXPI_CFG2_MASK, GTYE3_CH_TXPI_CFG2_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG5_ADDR, GTYE3_CH_TXPI_CFG5_MASK, GTYE3_CH_TXPI_CFG5_LSB, 0x0000}, + {GTYE3_CH_TX_PI_CFG0_ADDR, GTYE3_CH_TX_PI_CFG0_MASK, GTYE3_CH_TX_PI_CFG0_LSB, 0x0000}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye3_ch_preset_10g_lpm_regs[] = { + {GTYE3_CH_RXDFELPM_KL_CFG1_ADDR, GTYE3_CH_RXDFELPM_KL_CFG1_MASK, GTYE3_CH_RXDFELPM_KL_CFG1_LSB, 0x00E2}, + {GTYE3_CH_RXPI_CFG_ADDR, GTYE3_CH_RXPI_CFG_MASK, GTYE3_CH_RXPI_CFG_LSB, 0x566A}, + {GTYE3_CH_RX_DFE_AGC_CFG1_ADDR, GTYE3_CH_RX_DFE_AGC_CFG1_MASK, GTYE3_CH_RX_DFE_AGC_CFG1_LSB, 0x0002}, + {GTYE3_CH_TXPI_CFG0_ADDR, GTYE3_CH_TXPI_CFG0_MASK, GTYE3_CH_TXPI_CFG0_LSB, 0x0001}, + {GTYE3_CH_TXPI_CFG1_ADDR, GTYE3_CH_TXPI_CFG1_MASK, GTYE3_CH_TXPI_CFG1_LSB, 0x0001}, + {GTYE3_CH_TXPI_CFG2_ADDR, GTYE3_CH_TXPI_CFG2_MASK, GTYE3_CH_TXPI_CFG2_LSB, 0x0001}, + {GTYE3_CH_TXPI_CFG5_ADDR, GTYE3_CH_TXPI_CFG5_MASK, GTYE3_CH_TXPI_CFG5_LSB, 0x0003}, + {GTYE3_CH_TX_PI_CFG0_ADDR, GTYE3_CH_TX_PI_CFG0_MASK, GTYE3_CH_TX_PI_CFG0_LSB, 0x0002}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye3_ch_preset_25g_baser_64_regs[] = { + {GTYE3_CH_CH_HSPMUX_ADDR, GTYE3_CH_CH_HSPMUX_MASK, GTYE3_CH_CH_HSPMUX_LSB, 0xB6B6}, + {GTYE3_CH_CKCAL1_CFG_3_ADDR, GTYE3_CH_CKCAL1_CFG_3_MASK, GTYE3_CH_CKCAL1_CFG_3_LSB, 0x0007}, + {GTYE3_CH_CKCAL2_CFG_0_ADDR, GTYE3_CH_CKCAL2_CFG_0_MASK, GTYE3_CH_CKCAL2_CFG_0_LSB, 0x4040}, + {GTYE3_CH_CKCAL2_CFG_1_ADDR, GTYE3_CH_CKCAL2_CFG_1_MASK, GTYE3_CH_CKCAL2_CFG_1_LSB, 0x0040}, + {GTYE3_CH_CKCAL_RSVD1_ADDR, GTYE3_CH_CKCAL_RSVD1_MASK, GTYE3_CH_CKCAL_RSVD1_LSB, 0x0000}, + {GTYE3_CH_PMA_RSV0_ADDR, GTYE3_CH_PMA_RSV0_MASK, GTYE3_CH_PMA_RSV0_LSB, 0x2116}, + {GTYE3_CH_PMA_RSV1_ADDR, GTYE3_CH_PMA_RSV1_MASK, GTYE3_CH_PMA_RSV1_LSB, 0x504A}, + {GTYE3_CH_PREIQ_FREQ_BST_ADDR, GTYE3_CH_PREIQ_FREQ_BST_MASK, GTYE3_CH_PREIQ_FREQ_BST_LSB, 0x0002}, + {GTYE3_CH_RXCDR_CFG2_GEN3_ADDR, GTYE3_CH_RXCDR_CFG2_GEN3_MASK, GTYE3_CH_RXCDR_CFG2_GEN3_LSB, 0x01E9}, + {GTYE3_CH_RXCDR_CFG2_ADDR, GTYE3_CH_RXCDR_CFG2_MASK, GTYE3_CH_RXCDR_CFG2_LSB, 0x01E9}, + {GTYE3_CH_RXPI_CFG_ADDR, GTYE3_CH_RXPI_CFG_MASK, GTYE3_CH_RXPI_CFG_LSB, 0x0006}, + {GTYE3_CH_RX_DFE_KL_LPM_KH_CFG0_ADDR, GTYE3_CH_RX_DFE_KL_LPM_KH_CFG0_MASK, GTYE3_CH_RX_DFE_KL_LPM_KH_CFG0_LSB, 0x0001}, + {GTYE3_CH_RX_DFE_KL_LPM_KL_CFG0_ADDR, GTYE3_CH_RX_DFE_KL_LPM_KL_CFG0_MASK, GTYE3_CH_RX_DFE_KL_LPM_KL_CFG0_LSB, 0x0001}, + {GTYE3_CH_RX_PROGDIV_CFG_ADDR, GTYE3_CH_RX_PROGDIV_CFG_MASK, GTYE3_CH_RX_PROGDIV_CFG_LSB, GTYE3_CH_RX_PROGDIV_CFG_16P5}, + {GTYE3_CH_RX_PROGDIV_RATE_ADDR, GTYE3_CH_RX_PROGDIV_RATE_MASK, GTYE3_CH_RX_PROGDIV_RATE_LSB, GTYE3_CH_RX_PROGDIV_RATE_HALF}, + {GTYE3_CH_RX_WIDEMODE_CDR_ADDR, GTYE3_CH_RX_WIDEMODE_CDR_MASK, GTYE3_CH_RX_WIDEMODE_CDR_LSB, 0x0000}, + {GTYE3_CH_RX_XMODE_SEL_ADDR, GTYE3_CH_RX_XMODE_SEL_MASK, GTYE3_CH_RX_XMODE_SEL_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG3_ADDR, GTYE3_CH_TXPI_CFG3_MASK, GTYE3_CH_TXPI_CFG3_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG4_ADDR, GTYE3_CH_TXPI_CFG4_MASK, GTYE3_CH_TXPI_CFG4_LSB, 0x0000}, + {GTYE3_CH_TX_PI_BIASSET_ADDR, GTYE3_CH_TX_PI_BIASSET_MASK, GTYE3_CH_TX_PI_BIASSET_LSB, 0x0000}, + {GTYE3_CH_TX_PROGDIV_CFG_ADDR, GTYE3_CH_TX_PROGDIV_CFG_MASK, GTYE3_CH_TX_PROGDIV_CFG_LSB, GTYE3_CH_TX_PROGDIV_CFG_16P5}, + {GTYE3_CH_TX_PROGDIV_RATE_ADDR, GTYE3_CH_TX_PROGDIV_RATE_MASK, GTYE3_CH_TX_PROGDIV_RATE_LSB, GTYE3_CH_TX_PROGDIV_RATE_HALF}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye3_ch_preset_25g_dfe_regs[] = { + {GTYE3_CH_RXDFELPM_KL_CFG1_ADDR, GTYE3_CH_RXDFELPM_KL_CFG1_MASK, GTYE3_CH_RXDFELPM_KL_CFG1_LSB, 0x0002}, + {GTYE3_CH_RX_DFE_AGC_CFG1_ADDR, GTYE3_CH_RX_DFE_AGC_CFG1_MASK, GTYE3_CH_RX_DFE_AGC_CFG1_LSB, 0x0004}, + {GTYE3_CH_TXPI_CFG0_ADDR, GTYE3_CH_TXPI_CFG0_MASK, GTYE3_CH_TXPI_CFG0_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG1_ADDR, GTYE3_CH_TXPI_CFG1_MASK, GTYE3_CH_TXPI_CFG1_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG2_ADDR, GTYE3_CH_TXPI_CFG2_MASK, GTYE3_CH_TXPI_CFG2_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG5_ADDR, GTYE3_CH_TXPI_CFG5_MASK, GTYE3_CH_TXPI_CFG5_LSB, 0x0000}, + {GTYE3_CH_TX_PI_CFG0_ADDR, GTYE3_CH_TX_PI_CFG0_MASK, GTYE3_CH_TX_PI_CFG0_LSB, 0x0000}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye3_ch_preset_25g_lpm_regs[] = { + {GTYE3_CH_RXDFELPM_KL_CFG1_ADDR, GTYE3_CH_RXDFELPM_KL_CFG1_MASK, GTYE3_CH_RXDFELPM_KL_CFG1_LSB, 0x00E2}, + {GTYE3_CH_RX_DFE_AGC_CFG1_ADDR, GTYE3_CH_RX_DFE_AGC_CFG1_MASK, GTYE3_CH_RX_DFE_AGC_CFG1_LSB, 0x0002}, + {GTYE3_CH_TXPI_CFG0_ADDR, GTYE3_CH_TXPI_CFG0_MASK, GTYE3_CH_TXPI_CFG0_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG1_ADDR, GTYE3_CH_TXPI_CFG1_MASK, GTYE3_CH_TXPI_CFG1_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG2_ADDR, GTYE3_CH_TXPI_CFG2_MASK, GTYE3_CH_TXPI_CFG2_LSB, 0x0000}, + {GTYE3_CH_TXPI_CFG5_ADDR, GTYE3_CH_TXPI_CFG5_MASK, GTYE3_CH_TXPI_CFG5_LSB, 0x0000}, + {GTYE3_CH_TX_PI_CFG0_ADDR, GTYE3_CH_TX_PI_CFG0_MASK, GTYE3_CH_TX_PI_CFG0_LSB, 0x0000}, + {0, 0, 0, 0} +}; + +static const uint32_t gtye3_ch_presets[] = { + GT_PRESET_10G_DFE, + GT_PRESET_10G_LPM, + GT_PRESET_25G_DFE, + GT_PRESET_25G_LPM, + 0 +}; + +static int gtye3_ch_get_available_presets(struct gt_ch *ch, const uint32_t **presets) +{ + *presets = gtye3_ch_presets; + return 0; +} + +int gtye3_ch_load_preset(struct gt_ch *ch, uint32_t preset) +{ + struct gtye3_quad_priv *priv = ch->quad->priv; + + if (preset == GT_PRESET_10G_DFE || preset == GT_PRESET_10G_LPM) + { + if (priv->qpll0_25g) + gtye3_pll_set_qpll1_pd(ch->pll, 0); + + gtye3_ch_set_tx_reset(ch, 1); + gtye3_ch_set_rx_reset(ch, 1); + + if (priv->qpll0_25g) + { + gtye3_ch_set_tx_qpll_sel(ch, 1); + gtye3_ch_set_rx_qpll_sel(ch, 1); + } + + gt_ch_reg_write_multiple(ch, gtye3_ch_preset_10g_baser_64_regs); + + if (preset == GT_PRESET_10G_DFE) + { + gt_ch_reg_write_multiple(ch, gtye3_ch_preset_10g_dfe_regs); + gtye3_ch_set_rx_lpm_en(ch, 0); + } + else + { + gt_ch_reg_write_multiple(ch, gtye3_ch_preset_10g_lpm_regs); + gtye3_ch_set_rx_lpm_en(ch, 1); + } + + gtye3_ch_set_tx_reset(ch, 0); + gtye3_ch_set_rx_reset(ch, 0); + + return 0; + } + + if ((preset == GT_PRESET_25G_DFE || preset == GT_PRESET_25G_LPM) && priv->qpll0_25g) + { + gtye3_ch_set_tx_reset(ch, 1); + gtye3_ch_set_rx_reset(ch, 1); + + gtye3_ch_set_tx_qpll_sel(ch, 0); + gtye3_ch_set_rx_qpll_sel(ch, 0); + + gt_ch_reg_write_multiple(ch, gtye3_ch_preset_25g_baser_64_regs); + + if (preset == GT_PRESET_25G_DFE) + { + gt_ch_reg_write_multiple(ch, gtye3_ch_preset_25g_dfe_regs); + gtye3_ch_set_rx_lpm_en(ch, 0); + } + else + { + gt_ch_reg_write_multiple(ch, gtye3_ch_preset_25g_lpm_regs); + gtye3_ch_set_rx_lpm_en(ch, 1); + } + + gtye3_ch_set_tx_reset(ch, 0); + gtye3_ch_set_rx_reset(ch, 0); + + return 0; + } + + return -1; +} + +static int gtye3_ch_eyescan_start(struct gt_ch *ch, struct gt_eyescan_params *params) +{ + struct gtye3_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + float ber; + + priv->eyescan_running = 0; + + gtye3_ch_get_rx_lpm_en(ch, &val); + priv->dfe_en = !val; + + gtye3_ch_get_rx_data_width(ch, &priv->rx_data_width); + gtye3_ch_get_rx_int_data_width(ch, &priv->rx_int_data_width); + + priv->prescale = 0; + + for (priv->prescale = 0; priv->prescale < 32; priv->prescale++) + { + if (((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale) >= params->target_bit_count) + break; + } + + params->target_bit_count = ((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + params->h_range = 0; + + priv->h_start = params->h_start; + priv->h_stop = params->h_stop; + priv->h_step = params->h_step; + priv->v_range = params->v_range; + priv->v_start = params->v_start; + priv->v_stop = params->v_stop; + priv->v_step = params->v_step; + + gtye3_ch_set_es_control(ch, 0x00); + + gtye3_ch_set_es_prescale(ch, 4); + gtye3_ch_set_es_errdet_en(ch, 1); + + gtye3_ch_set_es_qual_mask_clear(ch); + gtye3_ch_set_es_sdata_mask_width(ch, priv->rx_int_data_width); + + gtye3_ch_set_rx_eyescan_vs_range(ch, priv->v_range); + + gtye3_ch_set_es_horz_offset(ch, 0x800); + gtye3_ch_set_rx_eyescan_vs_neg_dir(ch, 0); + gtye3_ch_set_rx_eyescan_vs_code(ch, 0); + gtye3_ch_set_rx_eyescan_vs_ut_sign(ch, 0); + + gtye3_ch_set_es_eye_scan_en(ch, 1); + + gtye3_ch_rx_pma_reset(ch); + + for (int ber_tries = 0; ber_tries < 10; ber_tries++) + { + for (int reset_tries = 0; reset_tries < 30; reset_tries++) + { + gtye3_ch_get_rx_reset_done(ch, &val); + if (val) + break; + usleep(100000); + } + + if (!val) + { + fprintf(stderr, "Error: channel stuck in reset\n"); + return -1; + } + + usleep(100000); + + // check for lock + gtye3_ch_set_es_control(ch, 0x01); + + for (int wait_tries = 0; wait_tries < 30; wait_tries++) + { + gtye3_ch_get_es_control_status(ch, &val); + if (val & 1) + break; + usleep(100000); + } + + if (!(val & 1)) + { + fprintf(stderr, "Error: eye scan did not finish (%d)\n", val); + return -1; + } + + gtye3_ch_set_es_control(ch, 0x00); + + gtye3_ch_get_es_error_count(ch, &error_count); + gtye3_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+4); + + ber = (float)error_count / (float)bit_count; + + if (ber < 0.01) + break; + + printf("High BER (%02f), resetting eye scan logic\n", ber); + + gtye3_ch_set_es_horz_offset(ch, 0x880); + gtye3_ch_set_eyescan_reset(ch, 1); + gtye3_ch_set_es_horz_offset(ch, 0x800); + gtye3_ch_set_eyescan_reset(ch, 0); + } + + if (ber > 0.01) + { + fprintf(stderr, "Error: High BER, alignment failed\n"); + return -1; + } + + // set up for measurement + priv->h_offset = priv->h_start; + priv->v_offset = priv->v_start; + priv->ut_sign = 0; + + gtye3_ch_set_es_control(ch, 0x00); + gtye3_ch_set_es_prescale(ch, priv->prescale); + gtye3_ch_set_es_errdet_en(ch, 1); + gtye3_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | 0x800); + gtye3_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gtye3_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + gtye3_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + // start measurement + gtye3_ch_set_es_control(ch, 0x01); + + priv->eyescan_running = 1; + + return 0; +} + +static int gtye3_ch_eyescan_step(struct gt_ch *ch, struct gt_eyescan_point *point) +{ + struct gtye3_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + + int restart = 0; + + if (!priv->eyescan_running) + return 0; + + gtye3_ch_get_es_control_status(ch, &val); + if (!(val & 1)) + return 2; + + gtye3_ch_set_es_control(ch, 0x00); + + gtye3_ch_get_es_error_count(ch, &error_count); + gtye3_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + + point->error_count = error_count; + point->bit_count = bit_count; + point->x = priv->h_offset; + point->y = priv->v_offset; + point->ut_sign = priv->ut_sign; + + restart = 0; + + if (!priv->ut_sign && priv->dfe_en) + { + priv->ut_sign = 1; + restart = 1; + } + else + { + priv->ut_sign = 0; + } + + gtye3_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + if (restart) + { + gtye3_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->v_offset < priv->v_stop) + { + priv->v_offset += priv->v_step; + restart = 1; + } + else + { + priv->v_offset = priv->v_start; + } + + gtye3_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gtye3_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + + if (restart) + { + gtye3_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->h_offset < priv->h_stop) + { + priv->h_offset += priv->h_step; + restart = 1; + } + else + { + // done + priv->eyescan_running = 0; + return 1; + } + + gtye3_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | 0x800); + + if (restart) + { + gtye3_ch_set_es_control(ch, 0x01); + return 1; + } + + priv->eyescan_running = 0; + return 0; +} + +const struct gt_ch_ops gtye3_gt_ch_ops = { + .get_tx_reset = gtye3_ch_get_tx_reset, + .set_tx_reset = gtye3_ch_set_tx_reset, + .tx_reset = gtye3_ch_tx_reset, + .get_rx_reset = gtye3_ch_get_rx_reset, + .set_rx_reset = gtye3_ch_set_rx_reset, + .rx_reset = gtye3_ch_rx_reset, + .get_tx_data_width = gtye3_ch_get_tx_data_width, + .get_tx_int_data_width = gtye3_ch_get_tx_int_data_width, + .get_rx_data_width = gtye3_ch_get_rx_data_width, + .get_rx_int_data_width = gtye3_ch_get_rx_int_data_width, + .get_available_presets = gtye3_ch_get_available_presets, + .load_preset = gtye3_ch_load_preset, + .eyescan_start = gtye3_ch_eyescan_start, + .eyescan_step = gtye3_ch_eyescan_step +}; + +static int gtye3_ch_init(struct gt_ch *ch) +{ + struct gtye3_ch_priv *priv = calloc(1, sizeof(struct gtye3_ch_priv)); + if (!priv) + return -1; + + ch->priv = priv; + + return 0; +} + +int gtye3_quad_init(struct gt_quad *quad) +{ + uint32_t val; + struct gtye3_quad_priv *priv = calloc(1, sizeof(struct gtye3_quad_priv)); + if (!priv) + return -1; + + quad->priv = priv; + quad->type = "GTYE3"; + + gtye3_pll_get_qpll0clkout_rate(&quad->pll, &val); + priv->qpll0_25g = val == GTYE3_COM_QPLL0CLKOUT_RATE_FULL; + + for (int n = 0; n < quad->ch_count; n++) + { + quad->ch[n].quad = quad; + quad->ch[n].pll = &quad->pll; + quad->ch[n].ops = >ye3_gt_ch_ops; + quad->ch[n].index = n; + + gtye3_ch_init(&quad->ch[n]); + } + + return 0; +} + +const struct gt_quad_ops gtye3_gt_quad_ops = { + .init = gtye3_quad_init +}; diff --git a/utils/xcvr_gtye3.h b/utils/xcvr_gtye3.h new file mode 100644 index 000000000..e2873d27c --- /dev/null +++ b/utils/xcvr_gtye3.h @@ -0,0 +1,402 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#ifndef XCVR_GTYE3_H +#define XCVR_GTYE3_H + +#include "xcvr_gt.h" +#include "gt/gtye3_regs.h" + +// signals +#define GTYE3_COM_QPLL0_RESET_ADDR 0x10000 +#define GTYE3_COM_QPLL0_RESET_MSB 0 +#define GTYE3_COM_QPLL0_RESET_LSB 0 +#define GTYE3_COM_QPLL0_RESET_MASK BIT_MASK(GTYE3_COM_QPLL0_RESET_MSB, GTYE3_COM_QPLL0_RESET_LSB) +#define GTYE3_COM_QPLL0_LOCK_ADDR 0x10000 +#define GTYE3_COM_QPLL0_LOCK_MSB 8 +#define GTYE3_COM_QPLL0_LOCK_LSB 8 +#define GTYE3_COM_QPLL0_LOCK_MASK BIT_MASK(GTYE3_COM_QPLL0_LOCK_MSB, GTYE3_COM_QPLL0_LOCK_LSB) +#define GTYE3_COM_QPLL0_PD_ADDR 0x10001 +#define GTYE3_COM_QPLL0_PD_MSB 0 +#define GTYE3_COM_QPLL0_PD_LSB 0 +#define GTYE3_COM_QPLL0_PD_MASK BIT_MASK(GTYE3_COM_QPLL0_PD_MSB, GTYE3_COM_QPLL0_PD_LSB) +#define GTYE3_COM_QPLL1_RESET_ADDR 0x11000 +#define GTYE3_COM_QPLL1_RESET_MSB 0 +#define GTYE3_COM_QPLL1_RESET_LSB 0 +#define GTYE3_COM_QPLL1_RESET_MASK BIT_MASK(GTYE3_COM_QPLL0_RESET_MSB, GTYE3_COM_QPLL0_RESET_LSB) +#define GTYE3_COM_QPLL1_LOCK_ADDR 0x11000 +#define GTYE3_COM_QPLL1_LOCK_MSB 8 +#define GTYE3_COM_QPLL1_LOCK_LSB 8 +#define GTYE3_COM_QPLL1_LOCK_MASK BIT_MASK(GTYE3_COM_QPLL0_LOCK_MSB, GTYE3_COM_QPLL0_LOCK_LSB) +#define GTYE3_COM_QPLL1_PD_ADDR 0x11001 +#define GTYE3_COM_QPLL1_PD_MSB 0 +#define GTYE3_COM_QPLL1_PD_LSB 0 +#define GTYE3_COM_QPLL1_PD_MASK BIT_MASK(GTYE3_COM_QPLL1_PD_MSB, GTYE3_COM_QPLL1_PD_LSB) + +#define GTYE3_CH_TX_RESET_ADDR 0x10000 +#define GTYE3_CH_TX_RESET_MSB 0 +#define GTYE3_CH_TX_RESET_LSB 0 +#define GTYE3_CH_TX_RESET_MASK BIT_MASK(GTYE3_CH_TX_RESET_MSB, GTYE3_CH_TX_RESET_LSB) +#define GTYE3_CH_TX_PMA_RESET_ADDR 0x10000 +#define GTYE3_CH_TX_PMA_RESET_MSB 1 +#define GTYE3_CH_TX_PMA_RESET_LSB 1 +#define GTYE3_CH_TX_PMA_RESET_MASK BIT_MASK(GTYE3_CH_TX_PMA_RESET_MSB, GTYE3_CH_TX_PMA_RESET_LSB) +#define GTYE3_CH_TX_PCS_RESET_ADDR 0x10000 +#define GTYE3_CH_TX_PCS_RESET_MSB 2 +#define GTYE3_CH_TX_PCS_RESET_LSB 2 +#define GTYE3_CH_TX_PCS_RESET_MASK BIT_MASK(GTYE3_CH_TX_PCS_RESET_MSB, GTYE3_CH_TX_PCS_RESET_LSB) +#define GTYE3_CH_TX_RESET_DONE_ADDR 0x10000 +#define GTYE3_CH_TX_RESET_DONE_MSB 8 +#define GTYE3_CH_TX_RESET_DONE_LSB 8 +#define GTYE3_CH_TX_RESET_DONE_MASK BIT_MASK(GTYE3_CH_TX_RESET_DONE_MSB, GTYE3_CH_TX_RESET_DONE_LSB) +#define GTYE3_CH_TX_GT_RESET_DONE_ADDR 0x10000 +#define GTYE3_CH_TX_GT_RESET_DONE_MSB 9 +#define GTYE3_CH_TX_GT_RESET_DONE_LSB 9 +#define GTYE3_CH_TX_GT_RESET_DONE_MASK BIT_MASK(GTYE3_CH_TX_GT_RESET_DONE_MSB, GTYE3_CH_TX_GT_RESET_DONE_LSB) +#define GTYE3_CH_TX_PMA_RESET_DONE_ADDR 0x10000 +#define GTYE3_CH_TX_PMA_RESET_DONE_MSB 10 +#define GTYE3_CH_TX_PMA_RESET_DONE_LSB 10 +#define GTYE3_CH_TX_PMA_RESET_DONE_MASK BIT_MASK(GTYE3_CH_TX_PMA_RESET_DONE_MSB, GTYE3_CH_TX_PMA_RESET_DONE_LSB) +#define GTYE3_CH_TX_PRGDIV_RESET_DONE_ADDR 0x10000 +#define GTYE3_CH_TX_PRGDIV_RESET_DONE_MSB 11 +#define GTYE3_CH_TX_PRGDIV_RESET_DONE_LSB 11 +#define GTYE3_CH_TX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTYE3_CH_TX_PRGDIV_RESET_DONE_MSB, GTYE3_CH_TX_PRGDIV_RESET_DONE_LSB) +#define GTYE3_CH_TX_USRCLK_ACT_ADDR 0x10000 +#define GTYE3_CH_TX_USRCLK_ACT_MSB 12 +#define GTYE3_CH_TX_USRCLK_ACT_LSB 12 +#define GTYE3_CH_TX_USRCLK_ACT_MASK BIT_MASK(GTYE3_CH_TX_USRCLK_ACT_MSB, GTYE3_CH_TX_USRCLK_ACT_LSB) +#define GTYE3_CH_TX_PD_ADDR 0x10001 +#define GTYE3_CH_TX_PD_MSB 0 +#define GTYE3_CH_TX_PD_LSB 0 +#define GTYE3_CH_TX_PD_MASK BIT_MASK(GTYE3_CH_TX_PD_MSB, GTYE3_CH_TX_PD_LSB) +#define GTYE3_CH_TX_QPLL_SEL_ADDR 0x10001 +#define GTYE3_CH_TX_QPLL_SEL_MSB 1 +#define GTYE3_CH_TX_QPLL_SEL_LSB 1 +#define GTYE3_CH_TX_QPLL_SEL_MASK BIT_MASK(GTYE3_CH_TX_QPLL_SEL_MSB, GTYE3_CH_TX_QPLL_SEL_LSB) +#define GTYE3_CH_TX_POLARITY_ADDR 0x10010 +#define GTYE3_CH_TX_POLARITY_MSB 0 +#define GTYE3_CH_TX_POLARITY_LSB 0 +#define GTYE3_CH_TX_POLARITY_MASK BIT_MASK(GTYE3_CH_TX_POLARITY_MSB, GTYE3_CH_TX_POLARITY_LSB) +#define GTYE3_CH_TX_ELECIDLE_ADDR 0x10010 +#define GTYE3_CH_TX_ELECIDLE_MSB 1 +#define GTYE3_CH_TX_ELECIDLE_LSB 1 +#define GTYE3_CH_TX_ELECIDLE_MASK BIT_MASK(GTYE3_CH_TX_ELECIDLE_MSB, GTYE3_CH_TX_ELECIDLE_LSB) +#define GTYE3_CH_TX_INHIBIT_ADDR 0x10010 +#define GTYE3_CH_TX_INHIBIT_MSB 2 +#define GTYE3_CH_TX_INHIBIT_LSB 2 +#define GTYE3_CH_TX_INHIBIT_MASK BIT_MASK(GTYE3_CH_TX_INHIBIT_MSB, GTYE3_CH_TX_INHIBIT_LSB) +#define GTYE3_CH_TX_DIFFCTRL_ADDR 0x10011 +#define GTYE3_CH_TX_DIFFCTRL_MSB 4 +#define GTYE3_CH_TX_DIFFCTRL_LSB 0 +#define GTYE3_CH_TX_DIFFCTRL_MASK BIT_MASK(GTYE3_CH_TX_DIFFCTRL_MSB, GTYE3_CH_TX_DIFFCTRL_LSB) +#define GTYE3_CH_TX_MAINCURSOR_ADDR 0x10012 +#define GTYE3_CH_TX_MAINCURSOR_MSB 6 +#define GTYE3_CH_TX_MAINCURSOR_LSB 0 +#define GTYE3_CH_TX_MAINCURSOR_MASK BIT_MASK(GTYE3_CH_TX_MAINCURSOR_MSB, GTYE3_CH_TX_MAINCURSOR_LSB) +#define GTYE3_CH_TX_PRECURSOR_ADDR 0x10013 +#define GTYE3_CH_TX_PRECURSOR_MSB 4 +#define GTYE3_CH_TX_PRECURSOR_LSB 0 +#define GTYE3_CH_TX_PRECURSOR_MASK BIT_MASK(GTYE3_CH_TX_PRECURSOR_MSB, GTYE3_CH_TX_PRECURSOR_LSB) +#define GTYE3_CH_TX_POSTCURSOR_ADDR 0x10014 +#define GTYE3_CH_TX_POSTCURSOR_MSB 4 +#define GTYE3_CH_TX_POSTCURSOR_LSB 0 +#define GTYE3_CH_TX_POSTCURSOR_MASK BIT_MASK(GTYE3_CH_TX_POSTCURSOR_MSB, GTYE3_CH_TX_POSTCURSOR_LSB) +#define GTYE3_CH_TX_PRBS_SEL_ADDR 0x10040 +#define GTYE3_CH_TX_PRBS_SEL_MSB 3 +#define GTYE3_CH_TX_PRBS_SEL_LSB 0 +#define GTYE3_CH_TX_PRBS_SEL_MASK BIT_MASK(GTYE3_CH_TX_PRBS_SEL_MSB, GTYE3_CH_TX_PRBS_SEL_LSB) +#define GTYE3_CH_TX_PRBS_FORCERR_ADDR 0x10040 +#define GTYE3_CH_TX_PRBS_FORCERR_MSB 15 +#define GTYE3_CH_TX_PRBS_FORCERR_LSB 0 +#define GTYE3_CH_TX_PRBS_FORCERR_MASK BIT_MASK(GTYE3_CH_TX_PRBS_FORCERR_MSB, GTYE3_CH_TX_PRBS_FORCERR_LSB) +#define GTYE3_CH_RX_RESET_ADDR 0x11000 +#define GTYE3_CH_RX_RESET_MSB 0 +#define GTYE3_CH_RX_RESET_LSB 0 +#define GTYE3_CH_RX_RESET_MASK BIT_MASK(GTYE3_CH_RX_RESET_MSB, GTYE3_CH_RX_RESET_LSB) +#define GTYE3_CH_RX_PMA_RESET_ADDR 0x11000 +#define GTYE3_CH_RX_PMA_RESET_MSB 1 +#define GTYE3_CH_RX_PMA_RESET_LSB 1 +#define GTYE3_CH_RX_PMA_RESET_MASK BIT_MASK(GTYE3_CH_RX_PMA_RESET_MSB, GTYE3_CH_RX_PMA_RESET_LSB) +#define GTYE3_CH_RX_PCS_RESET_ADDR 0x11000 +#define GTYE3_CH_RX_PCS_RESET_MSB 2 +#define GTYE3_CH_RX_PCS_RESET_LSB 2 +#define GTYE3_CH_RX_PCS_RESET_MASK BIT_MASK(GTYE3_CH_RX_PCS_RESET_MSB, GTYE3_CH_RX_PCS_RESET_LSB) +#define GTYE3_CH_RX_DFE_LPM_RESET_ADDR 0x11000 +#define GTYE3_CH_RX_DFE_LPM_RESET_MSB 3 +#define GTYE3_CH_RX_DFE_LPM_RESET_LSB 3 +#define GTYE3_CH_RX_DFE_LPM_RESET_MASK BIT_MASK(GTYE3_CH_RX_DFE_LPM_RESET_MSB, GTYE3_CH_RX_DFE_LPM_RESET_LSB) +#define GTYE3_CH_EYESCAN_RESET_ADDR 0x11000 +#define GTYE3_CH_EYESCAN_RESET_MSB 4 +#define GTYE3_CH_EYESCAN_RESET_LSB 4 +#define GTYE3_CH_EYESCAN_RESET_MASK BIT_MASK(GTYE3_CH_EYESCAN_RESET_MSB, GTYE3_CH_EYESCAN_RESET_LSB) +#define GTYE3_CH_RX_RESET_DONE_ADDR 0x11000 +#define GTYE3_CH_RX_RESET_DONE_MSB 8 +#define GTYE3_CH_RX_RESET_DONE_LSB 8 +#define GTYE3_CH_RX_RESET_DONE_MASK BIT_MASK(GTYE3_CH_RX_RESET_DONE_MSB, GTYE3_CH_RX_RESET_DONE_LSB) +#define GTYE3_CH_RX_GT_RESET_DONE_ADDR 0x11000 +#define GTYE3_CH_RX_GT_RESET_DONE_MSB 9 +#define GTYE3_CH_RX_GT_RESET_DONE_LSB 9 +#define GTYE3_CH_RX_GT_RESET_DONE_MASK BIT_MASK(GTYE3_CH_RX_GT_RESET_DONE_MSB, GTYE3_CH_RX_GT_RESET_DONE_LSB) +#define GTYE3_CH_RX_PMA_RESET_DONE_ADDR 0x11000 +#define GTYE3_CH_RX_PMA_RESET_DONE_MSB 10 +#define GTYE3_CH_RX_PMA_RESET_DONE_LSB 10 +#define GTYE3_CH_RX_PMA_RESET_DONE_MASK BIT_MASK(GTYE3_CH_RX_PMA_RESET_DONE_MSB, GTYE3_CH_RX_PMA_RESET_DONE_LSB) +#define GTYE3_CH_RX_PRGDIV_RESET_DONE_ADDR 0x11000 +#define GTYE3_CH_RX_PRGDIV_RESET_DONE_MSB 11 +#define GTYE3_CH_RX_PRGDIV_RESET_DONE_LSB 11 +#define GTYE3_CH_RX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTYE3_CH_RX_PRGDIV_RESET_DONE_MSB, GTYE3_CH_RX_PRGDIV_RESET_DONE_LSB) +#define GTYE3_CH_RX_USRCLK_ACT_ADDR 0x11000 +#define GTYE3_CH_RX_USRCLK_ACT_MSB 12 +#define GTYE3_CH_RX_USRCLK_ACT_LSB 12 +#define GTYE3_CH_RX_USRCLK_ACT_MASK BIT_MASK(GTYE3_CH_RX_USRCLK_ACT_MSB, GTYE3_CH_RX_USRCLK_ACT_LSB) +#define GTYE3_CH_RX_PD_ADDR 0x11001 +#define GTYE3_CH_RX_PD_MSB 0 +#define GTYE3_CH_RX_PD_LSB 0 +#define GTYE3_CH_RX_PD_MASK BIT_MASK(GTYE3_CH_RX_PD_MSB, GTYE3_CH_RX_PD_LSB) +#define GTYE3_CH_RX_QPLL_SEL_ADDR 0x11001 +#define GTYE3_CH_RX_QPLL_SEL_MSB 1 +#define GTYE3_CH_RX_QPLL_SEL_LSB 1 +#define GTYE3_CH_RX_QPLL_SEL_MASK BIT_MASK(GTYE3_CH_RX_QPLL_SEL_MSB, GTYE3_CH_RX_QPLL_SEL_LSB) +#define GTYE3_CH_LOOPBACK_ADDR 0x11002 +#define GTYE3_CH_LOOPBACK_MSB 2 +#define GTYE3_CH_LOOPBACK_LSB 0 +#define GTYE3_CH_LOOPBACK_MASK BIT_MASK(GTYE3_CH_LOOPBACK_MSB, GTYE3_CH_LOOPBACK_LSB) +#define GTYE3_CH_RX_POLARITY_ADDR 0x11010 +#define GTYE3_CH_RX_POLARITY_MSB 0 +#define GTYE3_CH_RX_POLARITY_LSB 0 +#define GTYE3_CH_RX_POLARITY_MASK BIT_MASK(GTYE3_CH_RX_POLARITY_MSB, GTYE3_CH_RX_POLARITY_LSB) +#define GTYE3_CH_RX_CDR_HOLD_ADDR 0x11020 +#define GTYE3_CH_RX_CDR_HOLD_MSB 0 +#define GTYE3_CH_RX_CDR_HOLD_LSB 0 +#define GTYE3_CH_RX_CDR_HOLD_MASK BIT_MASK(GTYE3_CH_RX_CDR_HOLD_MSB, GTYE3_CH_RX_CDR_HOLD_LSB) +#define GTYE3_CH_RX_CDR_LOCK_ADDR 0x11020 +#define GTYE3_CH_RX_CDR_LOCK_MSB 8 +#define GTYE3_CH_RX_CDR_LOCK_LSB 8 +#define GTYE3_CH_RX_CDR_LOCK_MASK BIT_MASK(GTYE3_CH_RX_CDR_LOCK_MSB, GTYE3_CH_RX_CDR_LOCK_LSB) +#define GTYE3_CH_RX_LPM_EN_ADDR 0x11024 +#define GTYE3_CH_RX_LPM_EN_MSB 0 +#define GTYE3_CH_RX_LPM_EN_LSB 0 +#define GTYE3_CH_RX_LPM_EN_MASK BIT_MASK(GTYE3_CH_RX_LPM_EN_MSB, GTYE3_CH_RX_LPM_EN_LSB) +#define GTYE3_CH_RX_DMONITOR_ADDR 0x11028 +#define GTYE3_CH_RX_DMONITOR_MSB 7 +#define GTYE3_CH_RX_DMONITOR_LSB 0 +#define GTYE3_CH_RX_DMONITOR_MASK BIT_MASK(GTYE3_CH_RX_DMONITOR_MSB, GTYE3_CH_RX_DMONITOR_LSB) +#define GTYE3_CH_RX_PRBS_SEL_ADDR 0x11040 +#define GTYE3_CH_RX_PRBS_SEL_MSB 3 +#define GTYE3_CH_RX_PRBS_SEL_LSB 0 +#define GTYE3_CH_RX_PRBS_SEL_MASK BIT_MASK(GTYE3_CH_RX_PRBS_SEL_MSB, GTYE3_CH_RX_PRBS_SEL_LSB) +#define GTYE3_CH_RX_PRBS_CNT_RESET_ADDR 0x11041 +#define GTYE3_CH_RX_PRBS_CNT_RESET_MSB 0 +#define GTYE3_CH_RX_PRBS_CNT_RESET_LSB 0 +#define GTYE3_CH_RX_PRBS_CNT_RESET_MASK BIT_MASK(GTYE3_CH_RX_PRBS_CNT_RESET_MSB, GTYE3_CH_RX_PRBS_CNT_RESET_LSB) +#define GTYE3_CH_RX_PRBS_LOCKED_ADDR 0x11041 +#define GTYE3_CH_RX_PRBS_LOCKED_MSB 8 +#define GTYE3_CH_RX_PRBS_LOCKED_LSB 8 +#define GTYE3_CH_RX_PRBS_LOCKED_MASK BIT_MASK(GTYE3_CH_RX_PRBS_LOCKED_MSB, GTYE3_CH_RX_PRBS_LOCKED_LSB) +#define GTYE3_CH_RX_PRBS_ERROR_ADDR 0x11041 +#define GTYE3_CH_RX_PRBS_ERROR_MSB 9 +#define GTYE3_CH_RX_PRBS_ERROR_LSB 9 +#define GTYE3_CH_RX_PRBS_ERROR_MASK BIT_MASK(GTYE3_CH_RX_PRBS_ERROR_MSB, GTYE3_CH_RX_PRBS_ERROR_LSB) + + +def_gt_pll_masked_reg_rw16(gtye3, qpll0_reset, GTYE3_COM_QPLL0_RESET_ADDR, GTYE3_COM_QPLL0_RESET_MASK, GTYE3_COM_QPLL0_RESET_LSB); +int gtye3_pll_qpll0_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gtye3, qpll0_lock, GTYE3_COM_QPLL0_LOCK_ADDR, GTYE3_COM_QPLL0_LOCK_MASK, GTYE3_COM_QPLL0_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_pd, GTYE3_COM_QPLL0_PD_ADDR, GTYE3_COM_QPLL0_PD_MASK, GTYE3_COM_QPLL0_PD_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_reset, GTYE3_COM_QPLL1_RESET_ADDR, GTYE3_COM_QPLL1_RESET_MASK, GTYE3_COM_QPLL1_RESET_LSB); +int gtye3_pll_qpll1_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gtye3, qpll1_lock, GTYE3_COM_QPLL1_LOCK_ADDR, GTYE3_COM_QPLL1_LOCK_MASK, GTYE3_COM_QPLL1_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_pd, GTYE3_COM_QPLL1_PD_ADDR, GTYE3_COM_QPLL1_PD_MASK, GTYE3_COM_QPLL1_PD_LSB); + +def_gt_ch_masked_reg_rw16(gtye3, tx_reset, GTYE3_CH_TX_RESET_ADDR, GTYE3_CH_TX_RESET_MASK, GTYE3_CH_TX_RESET_LSB); +int gtye3_ch_tx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye3, tx_pma_reset, GTYE3_CH_TX_PMA_RESET_ADDR, GTYE3_CH_TX_PMA_RESET_MASK, GTYE3_CH_TX_PMA_RESET_LSB); +int gtye3_ch_tx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye3, tx_pcs_reset, GTYE3_CH_TX_PCS_RESET_ADDR, GTYE3_CH_TX_PCS_RESET_MASK, GTYE3_CH_TX_PCS_RESET_LSB); +int gtye3_ch_tx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gtye3, tx_reset_done, GTYE3_CH_TX_RESET_DONE_ADDR, GTYE3_CH_TX_RESET_DONE_MASK, GTYE3_CH_TX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, tx_gt_reset_done, GTYE3_CH_TX_GT_RESET_DONE_ADDR, GTYE3_CH_TX_GT_RESET_DONE_MASK, GTYE3_CH_TX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, tx_pma_reset_done, GTYE3_CH_TX_PMA_RESET_DONE_ADDR, GTYE3_CH_TX_PMA_RESET_DONE_MASK, GTYE3_CH_TX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, tx_prgdiv_reset_done, GTYE3_CH_TX_PRGDIV_RESET_DONE_ADDR, GTYE3_CH_TX_PRGDIV_RESET_DONE_MASK, GTYE3_CH_TX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, tx_usrclk_act, GTYE3_CH_TX_USRCLK_ACT_ADDR, GTYE3_CH_TX_USRCLK_ACT_MASK, GTYE3_CH_TX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_pd, GTYE3_CH_TX_PD_ADDR, GTYE3_CH_TX_PD_MASK, GTYE3_CH_TX_PD_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_qpll_sel, GTYE3_CH_TX_QPLL_SEL_ADDR, GTYE3_CH_TX_QPLL_SEL_MASK, GTYE3_CH_TX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_polarity, GTYE3_CH_TX_POLARITY_ADDR, GTYE3_CH_TX_POLARITY_MASK, GTYE3_CH_TX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_elecidle, GTYE3_CH_TX_ELECIDLE_ADDR, GTYE3_CH_TX_ELECIDLE_MASK, GTYE3_CH_TX_ELECIDLE_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_inhibit, GTYE3_CH_TX_INHIBIT_ADDR, GTYE3_CH_TX_INHIBIT_MASK, GTYE3_CH_TX_INHIBIT_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_diffctrl, GTYE3_CH_TX_DIFFCTRL_ADDR, GTYE3_CH_TX_DIFFCTRL_MASK, GTYE3_CH_TX_DIFFCTRL_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_maincursor, GTYE3_CH_TX_MAINCURSOR_ADDR, GTYE3_CH_TX_MAINCURSOR_MASK, GTYE3_CH_TX_MAINCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_precursor, GTYE3_CH_TX_PRECURSOR_ADDR, GTYE3_CH_TX_PRECURSOR_MASK, GTYE3_CH_TX_PRECURSOR_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_postcursor, GTYE3_CH_TX_POSTCURSOR_ADDR, GTYE3_CH_TX_POSTCURSOR_MASK, GTYE3_CH_TX_POSTCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_prbs_sel, GTYE3_CH_TX_PRBS_SEL_ADDR, GTYE3_CH_TX_PRBS_SEL_MASK, GTYE3_CH_TX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye3, tx_prbs_forcerr, GTYE3_CH_TX_PRBS_FORCERR_ADDR, GTYE3_CH_TX_PRBS_FORCERR_MASK, GTYE3_CH_TX_PRBS_FORCERR_LSB); + +def_gt_ch_masked_reg_rw16(gtye3, rx_reset, GTYE3_CH_RX_RESET_ADDR, GTYE3_CH_RX_RESET_MASK, GTYE3_CH_RX_RESET_LSB); +int gtye3_ch_rx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye3, rx_pma_reset, GTYE3_CH_RX_PMA_RESET_ADDR, GTYE3_CH_RX_PMA_RESET_MASK, GTYE3_CH_RX_PMA_RESET_LSB); +int gtye3_ch_rx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye3, rx_pcs_reset, GTYE3_CH_RX_PCS_RESET_ADDR, GTYE3_CH_RX_PCS_RESET_MASK, GTYE3_CH_RX_PCS_RESET_LSB); +int gtye3_ch_rx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye3, rx_dfe_lpm_reset, GTYE3_CH_RX_DFE_LPM_RESET_ADDR, GTYE3_CH_RX_DFE_LPM_RESET_MASK, GTYE3_CH_RX_DFE_LPM_RESET_LSB); +int gtye3_ch_rx_dfe_lpm_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye3, eyescan_reset, GTYE3_CH_EYESCAN_RESET_ADDR, GTYE3_CH_EYESCAN_RESET_MASK, GTYE3_CH_EYESCAN_RESET_LSB); +int gtye3_ch_eyescan_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gtye3, rx_reset_done, GTYE3_CH_RX_RESET_DONE_ADDR, GTYE3_CH_RX_RESET_DONE_MASK, GTYE3_CH_RX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_gt_reset_done, GTYE3_CH_RX_GT_RESET_DONE_ADDR, GTYE3_CH_RX_GT_RESET_DONE_MASK, GTYE3_CH_RX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_pma_reset_done, GTYE3_CH_RX_PMA_RESET_DONE_ADDR, GTYE3_CH_RX_PMA_RESET_DONE_MASK, GTYE3_CH_RX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_prgdiv_reset_done, GTYE3_CH_RX_PRGDIV_RESET_DONE_ADDR, GTYE3_CH_RX_PRGDIV_RESET_DONE_MASK, GTYE3_CH_RX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_usrclk_act, GTYE3_CH_RX_USRCLK_ACT_ADDR, GTYE3_CH_RX_USRCLK_ACT_MASK, GTYE3_CH_RX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_pd, GTYE3_CH_RX_PD_ADDR, GTYE3_CH_RX_PD_MASK, GTYE3_CH_RX_PD_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_qpll_sel, GTYE3_CH_RX_QPLL_SEL_ADDR, GTYE3_CH_RX_QPLL_SEL_MASK, GTYE3_CH_RX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye3, loopback, GTYE3_CH_LOOPBACK_ADDR, GTYE3_CH_LOOPBACK_MASK, GTYE3_CH_LOOPBACK_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_polarity, GTYE3_CH_RX_POLARITY_ADDR, GTYE3_CH_RX_POLARITY_MASK, GTYE3_CH_RX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_cdr_hold, GTYE3_CH_RX_CDR_HOLD_ADDR, GTYE3_CH_RX_CDR_HOLD_MASK, GTYE3_CH_RX_CDR_HOLD_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_cdr_lock, GTYE3_CH_RX_CDR_LOCK_ADDR, GTYE3_CH_RX_CDR_LOCK_MASK, GTYE3_CH_RX_CDR_LOCK_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_lpm_en, GTYE3_CH_RX_LPM_EN_ADDR, GTYE3_CH_RX_LPM_EN_MASK, GTYE3_CH_RX_LPM_EN_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_dmonitor, GTYE3_CH_RX_DMONITOR_ADDR, GTYE3_CH_RX_DMONITOR_MASK, GTYE3_CH_RX_DMONITOR_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_prbs_sel, GTYE3_CH_RX_PRBS_SEL_ADDR, GTYE3_CH_RX_PRBS_SEL_MASK, GTYE3_CH_RX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_prbs_cnt_reset, GTYE3_CH_RX_PRBS_CNT_RESET_ADDR, GTYE3_CH_RX_PRBS_CNT_RESET_MASK, GTYE3_CH_RX_PRBS_CNT_RESET_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_prbs_locked, GTYE3_CH_RX_PRBS_LOCKED_ADDR, GTYE3_CH_RX_PRBS_LOCKED_MASK, GTYE3_CH_RX_PRBS_LOCKED_LSB); +def_gt_ch_masked_reg_read16(gtye3, rx_prbs_error, GTYE3_CH_RX_PRBS_ERROR_ADDR, GTYE3_CH_RX_PRBS_ERROR_MASK, GTYE3_CH_RX_PRBS_ERROR_LSB); + +// common +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cfg0, GTYE3_COM_QPLL0_CFG0_ADDR, GTYE3_COM_QPLL0_CFG0_MASK, GTYE3_COM_QPLL0_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, common_cfg0, GTYE3_COM_COMMON_CFG0_ADDR, GTYE3_COM_COMMON_CFG0_MASK, GTYE3_COM_COMMON_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, rsvd_attr0, GTYE3_COM_RSVD_ATTR0_ADDR, GTYE3_COM_RSVD_ATTR0_MASK, GTYE3_COM_RSVD_ATTR0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, ppf0_cfg, GTYE3_COM_PPF0_CFG_ADDR, GTYE3_COM_PPF0_CFG_MASK, GTYE3_COM_PPF0_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0clkout_rate, GTYE3_COM_QPLL0CLKOUT_RATE_ADDR, GTYE3_COM_QPLL0CLKOUT_RATE_MASK, GTYE3_COM_QPLL0CLKOUT_RATE_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cfg1, GTYE3_COM_QPLL0_CFG1_ADDR, GTYE3_COM_QPLL0_CFG1_MASK, GTYE3_COM_QPLL0_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cfg2, GTYE3_COM_QPLL0_CFG2_ADDR, GTYE3_COM_QPLL0_CFG2_MASK, GTYE3_COM_QPLL0_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_lock_cfg, GTYE3_COM_QPLL0_LOCK_CFG_ADDR, GTYE3_COM_QPLL0_LOCK_CFG_MASK, GTYE3_COM_QPLL0_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_init_cfg0, GTYE3_COM_QPLL0_INIT_CFG0_ADDR, GTYE3_COM_QPLL0_INIT_CFG0_MASK, GTYE3_COM_QPLL0_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_init_cfg1, GTYE3_COM_QPLL0_INIT_CFG1_ADDR, GTYE3_COM_QPLL0_INIT_CFG1_MASK, GTYE3_COM_QPLL0_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_fbdiv, GTYE3_COM_QPLL0_FBDIV_ADDR, GTYE3_COM_QPLL0_FBDIV_MASK, GTYE3_COM_QPLL0_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cfg3, GTYE3_COM_QPLL0_CFG3_ADDR, GTYE3_COM_QPLL0_CFG3_MASK, GTYE3_COM_QPLL0_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cp, GTYE3_COM_QPLL0_CP_ADDR, GTYE3_COM_QPLL0_CP_MASK, GTYE3_COM_QPLL0_CP_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_refclk_div, GTYE3_COM_QPLL0_REFCLK_DIV_ADDR, GTYE3_COM_QPLL0_REFCLK_DIV_MASK, GTYE3_COM_QPLL0_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_ips_refclk_sel, GTYE3_COM_QPLL0_IPS_REFCLK_SEL_ADDR, GTYE3_COM_QPLL0_IPS_REFCLK_SEL_MASK, GTYE3_COM_QPLL0_IPS_REFCLK_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_ips_en, GTYE3_COM_QPLL0_IPS_EN_ADDR, GTYE3_COM_QPLL0_IPS_EN_MASK, GTYE3_COM_QPLL0_IPS_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_lpf, GTYE3_COM_QPLL0_LPF_ADDR, GTYE3_COM_QPLL0_LPF_MASK, GTYE3_COM_QPLL0_LPF_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cfg1_g3, GTYE3_COM_QPLL0_CFG1_G3_ADDR, GTYE3_COM_QPLL0_CFG1_G3_MASK, GTYE3_COM_QPLL0_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cfg2_g3, GTYE3_COM_QPLL0_CFG2_G3_ADDR, GTYE3_COM_QPLL0_CFG2_G3_MASK, GTYE3_COM_QPLL0_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_lpf_g3, GTYE3_COM_QPLL0_LPF_G3_ADDR, GTYE3_COM_QPLL0_LPF_G3_MASK, GTYE3_COM_QPLL0_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_lock_cfg_g3, GTYE3_COM_QPLL0_LOCK_CFG_G3_ADDR, GTYE3_COM_QPLL0_LOCK_CFG_G3_MASK, GTYE3_COM_QPLL0_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, rsvd_attr1, GTYE3_COM_RSVD_ATTR1_ADDR, GTYE3_COM_RSVD_ATTR1_MASK, GTYE3_COM_RSVD_ATTR1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_fbdiv_g3, GTYE3_COM_QPLL0_FBDIV_G3_ADDR, GTYE3_COM_QPLL0_FBDIV_G3_MASK, GTYE3_COM_QPLL0_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, rxrecclkout0_sel, GTYE3_COM_RXRECCLKOUT0_SEL_ADDR, GTYE3_COM_RXRECCLKOUT0_SEL_MASK, GTYE3_COM_RXRECCLKOUT0_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_sdm_cfg0, GTYE3_COM_QPLL0_SDM_CFG0_ADDR, GTYE3_COM_QPLL0_SDM_CFG0_MASK, GTYE3_COM_QPLL0_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_sdm_cfg1, GTYE3_COM_QPLL0_SDM_CFG1_ADDR, GTYE3_COM_QPLL0_SDM_CFG1_MASK, GTYE3_COM_QPLL0_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, sdm0initseed0_0, GTYE3_COM_SDM0INITSEED0_0_ADDR, GTYE3_COM_SDM0INITSEED0_0_MASK, GTYE3_COM_SDM0INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, sdm0initseed0_1, GTYE3_COM_SDM0INITSEED0_1_ADDR, GTYE3_COM_SDM0INITSEED0_1_MASK, GTYE3_COM_SDM0INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_sdm_cfg2, GTYE3_COM_QPLL0_SDM_CFG2_ADDR, GTYE3_COM_QPLL0_SDM_CFG2_MASK, GTYE3_COM_QPLL0_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cp_g3, GTYE3_COM_QPLL0_CP_G3_ADDR, GTYE3_COM_QPLL0_CP_G3_MASK, GTYE3_COM_QPLL0_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll0_cfg4, GTYE3_COM_QPLL0_CFG4_ADDR, GTYE3_COM_QPLL0_CFG4_MASK, GTYE3_COM_QPLL0_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gtye3, bias_cfg0, GTYE3_COM_BIAS_CFG0_ADDR, GTYE3_COM_BIAS_CFG0_MASK, GTYE3_COM_BIAS_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, bias_cfg1, GTYE3_COM_BIAS_CFG1_ADDR, GTYE3_COM_BIAS_CFG1_MASK, GTYE3_COM_BIAS_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, bias_cfg2, GTYE3_COM_BIAS_CFG2_ADDR, GTYE3_COM_BIAS_CFG2_MASK, GTYE3_COM_BIAS_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye3, bias_cfg3, GTYE3_COM_BIAS_CFG3_ADDR, GTYE3_COM_BIAS_CFG3_MASK, GTYE3_COM_BIAS_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, bias_cfg4, GTYE3_COM_BIAS_CFG4_ADDR, GTYE3_COM_BIAS_CFG4_MASK, GTYE3_COM_BIAS_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cfg0, GTYE3_COM_QPLL1_CFG0_ADDR, GTYE3_COM_QPLL1_CFG0_MASK, GTYE3_COM_QPLL1_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, common_cfg1, GTYE3_COM_COMMON_CFG1_ADDR, GTYE3_COM_COMMON_CFG1_MASK, GTYE3_COM_COMMON_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, por_cfg, GTYE3_COM_POR_CFG_ADDR, GTYE3_COM_POR_CFG_MASK, GTYE3_COM_POR_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye3, ppf1_cfg, GTYE3_COM_PPF1_CFG_ADDR, GTYE3_COM_PPF1_CFG_MASK, GTYE3_COM_PPF1_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1clkout_rate, GTYE3_COM_QPLL1CLKOUT_RATE_ADDR, GTYE3_COM_QPLL1CLKOUT_RATE_MASK, GTYE3_COM_QPLL1CLKOUT_RATE_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cfg1, GTYE3_COM_QPLL1_CFG1_ADDR, GTYE3_COM_QPLL1_CFG1_MASK, GTYE3_COM_QPLL1_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cfg2, GTYE3_COM_QPLL1_CFG2_ADDR, GTYE3_COM_QPLL1_CFG2_MASK, GTYE3_COM_QPLL1_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_lock_cfg, GTYE3_COM_QPLL1_LOCK_CFG_ADDR, GTYE3_COM_QPLL1_LOCK_CFG_MASK, GTYE3_COM_QPLL1_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_init_cfg0, GTYE3_COM_QPLL1_INIT_CFG0_ADDR, GTYE3_COM_QPLL1_INIT_CFG0_MASK, GTYE3_COM_QPLL1_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_init_cfg1, GTYE3_COM_QPLL1_INIT_CFG1_ADDR, GTYE3_COM_QPLL1_INIT_CFG1_MASK, GTYE3_COM_QPLL1_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_fbdiv, GTYE3_COM_QPLL1_FBDIV_ADDR, GTYE3_COM_QPLL1_FBDIV_MASK, GTYE3_COM_QPLL1_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cfg3, GTYE3_COM_QPLL1_CFG3_ADDR, GTYE3_COM_QPLL1_CFG3_MASK, GTYE3_COM_QPLL1_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cp, GTYE3_COM_QPLL1_CP_ADDR, GTYE3_COM_QPLL1_CP_MASK, GTYE3_COM_QPLL1_CP_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_refclk_div, GTYE3_COM_QPLL1_REFCLK_DIV_ADDR, GTYE3_COM_QPLL1_REFCLK_DIV_MASK, GTYE3_COM_QPLL1_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_ips_refclk_sel, GTYE3_COM_QPLL1_IPS_REFCLK_SEL_ADDR, GTYE3_COM_QPLL1_IPS_REFCLK_SEL_MASK, GTYE3_COM_QPLL1_IPS_REFCLK_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye3, sarc_en, GTYE3_COM_SARC_EN_ADDR, GTYE3_COM_SARC_EN_MASK, GTYE3_COM_SARC_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_ips_en, GTYE3_COM_QPLL1_IPS_EN_ADDR, GTYE3_COM_QPLL1_IPS_EN_MASK, GTYE3_COM_QPLL1_IPS_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye3, sarc_sel, GTYE3_COM_SARC_SEL_ADDR, GTYE3_COM_SARC_SEL_MASK, GTYE3_COM_SARC_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_lpf, GTYE3_COM_QPLL1_LPF_ADDR, GTYE3_COM_QPLL1_LPF_MASK, GTYE3_COM_QPLL1_LPF_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cfg1_g3, GTYE3_COM_QPLL1_CFG1_G3_ADDR, GTYE3_COM_QPLL1_CFG1_G3_MASK, GTYE3_COM_QPLL1_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cfg2_g3, GTYE3_COM_QPLL1_CFG2_G3_ADDR, GTYE3_COM_QPLL1_CFG2_G3_MASK, GTYE3_COM_QPLL1_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_lpf_g3, GTYE3_COM_QPLL1_LPF_G3_ADDR, GTYE3_COM_QPLL1_LPF_G3_MASK, GTYE3_COM_QPLL1_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_lock_cfg_g3, GTYE3_COM_QPLL1_LOCK_CFG_G3_ADDR, GTYE3_COM_QPLL1_LOCK_CFG_G3_MASK, GTYE3_COM_QPLL1_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, rsvd_attr2, GTYE3_COM_RSVD_ATTR2_ADDR, GTYE3_COM_RSVD_ATTR2_MASK, GTYE3_COM_RSVD_ATTR2_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_fbdiv_g3, GTYE3_COM_QPLL1_FBDIV_G3_ADDR, GTYE3_COM_QPLL1_FBDIV_G3_MASK, GTYE3_COM_QPLL1_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, rxrecclkout1_sel, GTYE3_COM_RXRECCLKOUT1_SEL_ADDR, GTYE3_COM_RXRECCLKOUT1_SEL_MASK, GTYE3_COM_RXRECCLKOUT1_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_sdm_cfg0, GTYE3_COM_QPLL1_SDM_CFG0_ADDR, GTYE3_COM_QPLL1_SDM_CFG0_MASK, GTYE3_COM_QPLL1_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_sdm_cfg1, GTYE3_COM_QPLL1_SDM_CFG1_ADDR, GTYE3_COM_QPLL1_SDM_CFG1_MASK, GTYE3_COM_QPLL1_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, sdm1initseed0_0, GTYE3_COM_SDM1INITSEED0_0_ADDR, GTYE3_COM_SDM1INITSEED0_0_MASK, GTYE3_COM_SDM1INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gtye3, sdm1initseed0_1, GTYE3_COM_SDM1INITSEED0_1_ADDR, GTYE3_COM_SDM1INITSEED0_1_MASK, GTYE3_COM_SDM1INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_sdm_cfg2, GTYE3_COM_QPLL1_SDM_CFG2_ADDR, GTYE3_COM_QPLL1_SDM_CFG2_MASK, GTYE3_COM_QPLL1_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cp_g3, GTYE3_COM_QPLL1_CP_G3_ADDR, GTYE3_COM_QPLL1_CP_G3_MASK, GTYE3_COM_QPLL1_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, rsvd_attr3, GTYE3_COM_RSVD_ATTR3_ADDR, GTYE3_COM_RSVD_ATTR3_MASK, GTYE3_COM_RSVD_ATTR3_LSB); +def_gt_pll_masked_reg_rw16(gtye3, qpll1_cfg4, GTYE3_COM_QPLL1_CFG4_ADDR, GTYE3_COM_QPLL1_CFG4_MASK, GTYE3_COM_QPLL1_CFG4_LSB); + +// RX +def_gt_ch_masked_reg_rw16(gtye3, rx_data_width_raw, GTYE3_CH_RX_DATA_WIDTH_ADDR, GTYE3_CH_RX_DATA_WIDTH_MASK, GTYE3_CH_RX_DATA_WIDTH_LSB); +int gtye3_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gtye3, rx_int_data_width_raw, GTYE3_CH_RX_INT_DATAWIDTH_ADDR, GTYE3_CH_RX_INT_DATAWIDTH_MASK, GTYE3_CH_RX_INT_DATAWIDTH_LSB); +int gtye3_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gtye3, es_prescale, GTYE3_CH_ES_PRESCALE_ADDR, GTYE3_CH_ES_PRESCALE_MASK, GTYE3_CH_ES_PRESCALE_LSB); +def_gt_ch_masked_reg_rw16(gtye3, es_eye_scan_en, GTYE3_CH_ES_EYE_SCAN_EN_ADDR, GTYE3_CH_ES_EYE_SCAN_EN_MASK, GTYE3_CH_ES_EYE_SCAN_EN_LSB); +def_gt_ch_masked_reg_rw16(gtye3, es_errdet_en, GTYE3_CH_ES_ERRDET_EN_ADDR, GTYE3_CH_ES_ERRDET_EN_MASK, GTYE3_CH_ES_ERRDET_EN_LSB); +def_gt_ch_masked_reg_rw16(gtye3, es_control, GTYE3_CH_ES_CONTROL_ADDR, GTYE3_CH_ES_CONTROL_MASK, GTYE3_CH_ES_CONTROL_LSB); + +int gtye3_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask); +int gtye3_ch_set_es_qual_mask_clear(struct gt_ch *ch); + +int gtye3_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask); +int gtye3_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width); + +def_gt_ch_masked_reg_rw16(gtye3, es_horz_offset, GTYE3_CH_ES_HORZ_OFFSET_ADDR, GTYE3_CH_ES_HORZ_OFFSET_MASK, GTYE3_CH_ES_HORZ_OFFSET_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_eyescan_vs_range, GTYE3_CH_RX_EYESCAN_VS_RANGE_ADDR, GTYE3_CH_RX_EYESCAN_VS_RANGE_MASK, GTYE3_CH_RX_EYESCAN_VS_RANGE_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_eyescan_vs_code, GTYE3_CH_RX_EYESCAN_VS_CODE_ADDR, GTYE3_CH_RX_EYESCAN_VS_CODE_MASK, GTYE3_CH_RX_EYESCAN_VS_CODE_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_eyescan_vs_ut_sign, GTYE3_CH_RX_EYESCAN_VS_UT_SIGN_ADDR, GTYE3_CH_RX_EYESCAN_VS_UT_SIGN_MASK, GTYE3_CH_RX_EYESCAN_VS_UT_SIGN_LSB); +def_gt_ch_masked_reg_rw16(gtye3, rx_eyescan_vs_neg_dir, GTYE3_CH_RX_EYESCAN_VS_NEG_DIR_ADDR, GTYE3_CH_RX_EYESCAN_VS_NEG_DIR_MASK, GTYE3_CH_RX_EYESCAN_VS_NEG_DIR_LSB); +def_gt_ch_masked_reg_read16(gtye3, es_error_count, GTYE3_CH_ES_ERROR_COUNT_ADDR, GTYE3_CH_ES_ERROR_COUNT_MASK, GTYE3_CH_ES_ERROR_COUNT_LSB); +def_gt_ch_masked_reg_read16(gtye3, es_sample_count, GTYE3_CH_ES_SAMPLE_COUNT_ADDR, GTYE3_CH_ES_SAMPLE_COUNT_MASK, GTYE3_CH_ES_SAMPLE_COUNT_LSB); +def_gt_ch_masked_reg_read16(gtye3, es_control_status, GTYE3_CH_ES_CONTROL_STATUS_ADDR, GTYE3_CH_ES_CONTROL_STATUS_MASK, GTYE3_CH_ES_CONTROL_STATUS_LSB); + +int gtye3_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val); + +// TX +def_gt_ch_masked_reg_rw16(gtye3, tx_data_width_raw, GTYE3_CH_TX_DATA_WIDTH_ADDR, GTYE3_CH_TX_DATA_WIDTH_MASK, GTYE3_CH_TX_DATA_WIDTH_LSB); +int gtye3_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gtye3, tx_int_data_width_raw, GTYE3_CH_TX_INT_DATAWIDTH_ADDR, GTYE3_CH_TX_INT_DATAWIDTH_MASK, GTYE3_CH_TX_INT_DATAWIDTH_LSB); +int gtye3_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val); + +extern const struct gt_quad_ops gtye3_gt_quad_ops; + +#endif /* XCVR_GTYE3_H */ diff --git a/utils/xcvr_gtye4.c b/utils/xcvr_gtye4.c new file mode 100644 index 000000000..ce2cbda31 --- /dev/null +++ b/utils/xcvr_gtye4.c @@ -0,0 +1,817 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#include +#include +#include "xcvr_gtye4.h" + +// signals +int gtye4_pll_qpll0_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gtye4_pll_set_qpll0_reset(pll, 1); + + if (ret) + return ret; + + return gtye4_pll_set_qpll0_reset(pll, 0); +} + +int gtye4_pll_qpll1_reset(struct gt_pll *pll) +{ + int ret = 0; + + ret = gtye4_pll_set_qpll1_reset(pll, 1); + + if (ret) + return ret; + + return gtye4_pll_set_qpll1_reset(pll, 0); +} + +int gtye4_ch_tx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_tx_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_tx_reset(ch, 0); +} + +int gtye4_ch_tx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_tx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_tx_pma_reset(ch, 0); +} + +int gtye4_ch_tx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_tx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_tx_pcs_reset(ch, 0); +} + +int gtye4_ch_rx_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_rx_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_rx_reset(ch, 0); +} + +int gtye4_ch_rx_pma_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_rx_pma_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_rx_pma_reset(ch, 0); +} + +int gtye4_ch_rx_pcs_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_rx_pcs_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_rx_pcs_reset(ch, 0); +} + +int gtye4_ch_rx_dfe_lpm_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_rx_dfe_lpm_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_rx_dfe_lpm_reset(ch, 0); +} + +int gtye4_ch_eyescan_reset(struct gt_ch *ch) +{ + int ret = 0; + + ret = gtye4_ch_set_eyescan_reset(ch, 1); + + if (ret) + return ret; + + return gtye4_ch_set_eyescan_reset(ch, 0); +} + +// RX +int gtye4_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gtye4_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gtye4_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gtye4_ch_get_rx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gtye4_ch_get_rx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gtye4_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_QUAL_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_QUAL_MASK5_ADDR+k, mask[2*k+10] | (mask[2*k+11] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gtye4_ch_set_es_qual_mask_clear(struct gt_ch *ch) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_QUAL_MASK0_ADDR+k, 0xffff); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_QUAL_MASK5_ADDR+k, 0xffff); + if (ret) + return ret; + } + + return 0; +} + +int gtye4_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_SDATA_MASK0_ADDR+k, mask[2*k+0] | (mask[2*k+1] << 8)); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_SDATA_MASK5_ADDR+k, mask[2*k+10] | (mask[2*k+11] << 8)); + if (ret) + return ret; + } + + return 0; +} + +int gtye4_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width) +{ + int ret = 0; + + for (int k = 0; k < 5; k++) + { + int shift = width - (80 - ((k+1)*16)); + uint32_t mask = 0xffff; + + if (shift < 0) + { + mask = 0xffff; + } + else if (shift > 16) + { + mask = 0x0000; + } + else + { + mask = 0xffff >> shift; + } + + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_SDATA_MASK0_ADDR+k, mask); + if (ret) + return ret; + ret = gt_ch_reg_write(ch, GTYE4_CH_ES_SDATA_MASK5_ADDR+k, 0xffff); + if (ret) + return ret; + } + + return 0; +} + +int gtye4_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t v1, v2; + + ret = gt_ch_reg_read(ch, GTYE4_CH_RX_PRBS_ERR_CNT_L_ADDR | (ch->index << 17), &v1); + if (ret) + return ret; + + ret = gt_ch_reg_read(ch, GTYE4_CH_RX_PRBS_ERR_CNT_H_ADDR | (ch->index << 17), &v2); + if (ret) + return ret; + + *val = v1 | (v2 << 16); + return 0; +} + +// TX +int gtye4_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw; + + ret = gtye4_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + *val = (8*(1 << (dw >> 1)) * (4 + (dw & 1))) >> 2; + return 0; +} + +int gtye4_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val) +{ + int ret = 0; + uint32_t dw, idw; + + ret = gtye4_ch_get_tx_data_width_raw(ch, &dw); + if (ret) + return ret; + + ret = gtye4_ch_get_tx_int_data_width_raw(ch, &idw); + if (ret) + return ret; + + *val = (16*(1 << idw) * (4 + (dw & 1))) >> 2; + return 0; +} + +struct gtye4_quad_priv { + int qpll0_25g; +}; + +struct gtye4_ch_priv { + uint32_t tx_data_width; + uint32_t tx_int_data_width; + uint32_t rx_data_width; + uint32_t rx_int_data_width; + int dfe_en; + + int prescale; + int h_start; + int h_stop; + int h_step; + int v_range; + int v_start; + int v_stop; + int v_step; + + int h_offset; + int v_offset; + int ut_sign; + int eyescan_running; +}; + +static const struct gt_reg_val gtye4_ch_preset_10g_baser_64_regs[] = { + {GTYE4_CH_CH_HSPMUX_ADDR, GTYE4_CH_CH_HSPMUX_MASK, GTYE4_CH_CH_HSPMUX_LSB, 0x4040}, + {GTYE4_CH_CKCAL1_CFG_0_ADDR, GTYE4_CH_CKCAL1_CFG_0_MASK, GTYE4_CH_CKCAL1_CFG_0_LSB, 0xC0C0}, + {GTYE4_CH_CKCAL1_CFG_1_ADDR, GTYE4_CH_CKCAL1_CFG_1_MASK, GTYE4_CH_CKCAL1_CFG_1_LSB, 0x10C0}, + {GTYE4_CH_CKCAL2_CFG_0_ADDR, GTYE4_CH_CKCAL2_CFG_0_MASK, GTYE4_CH_CKCAL2_CFG_0_LSB, 0xC0C0}, + {GTYE4_CH_CKCAL2_CFG_1_ADDR, GTYE4_CH_CKCAL2_CFG_1_MASK, GTYE4_CH_CKCAL2_CFG_1_LSB, 0x80C0}, + {GTYE4_CH_PREIQ_FREQ_BST_ADDR, GTYE4_CH_PREIQ_FREQ_BST_MASK, GTYE4_CH_PREIQ_FREQ_BST_LSB, 0x0001}, + {GTYE4_CH_RTX_BUF_CML_CTRL_ADDR, GTYE4_CH_RTX_BUF_CML_CTRL_MASK, GTYE4_CH_RTX_BUF_CML_CTRL_LSB, 0x0003}, + {GTYE4_CH_RTX_BUF_TERM_CTRL_ADDR, GTYE4_CH_RTX_BUF_TERM_CTRL_MASK, GTYE4_CH_RTX_BUF_TERM_CTRL_LSB, 0x0000}, + {GTYE4_CH_RXCDR_CFG2_ADDR, GTYE4_CH_RXCDR_CFG2_MASK, GTYE4_CH_RXCDR_CFG2_LSB, 0x0269}, + {GTYE4_CH_RXCDR_CFG3_GEN2_ADDR, GTYE4_CH_RXCDR_CFG3_GEN2_MASK, GTYE4_CH_RXCDR_CFG3_GEN2_LSB, 0x0012}, + {GTYE4_CH_RXCDR_CFG3_GEN3_ADDR, GTYE4_CH_RXCDR_CFG3_GEN3_MASK, GTYE4_CH_RXCDR_CFG3_GEN3_LSB, 0x0012}, + {GTYE4_CH_RXCDR_CFG3_GEN4_ADDR, GTYE4_CH_RXCDR_CFG3_GEN4_MASK, GTYE4_CH_RXCDR_CFG3_GEN4_LSB, 0x0012}, + {GTYE4_CH_RXCDR_CFG3_ADDR, GTYE4_CH_RXCDR_CFG3_MASK, GTYE4_CH_RXCDR_CFG3_LSB, 0x0012}, + {GTYE4_CH_RXCKCAL1_IQ_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL1_IQ_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL1_IQ_LOOP_RST_CFG_LSB, 0x0000}, + {GTYE4_CH_RXCKCAL1_I_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL1_I_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL1_I_LOOP_RST_CFG_LSB, 0x0000}, + {GTYE4_CH_RXCKCAL1_Q_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL1_Q_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL1_Q_LOOP_RST_CFG_LSB, 0x0000}, + {GTYE4_CH_RXCKCAL2_DX_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_DX_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_DX_LOOP_RST_CFG_LSB, 0x0000}, + {GTYE4_CH_RXCKCAL2_D_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_D_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_D_LOOP_RST_CFG_LSB, 0x0000}, + {GTYE4_CH_RXCKCAL2_S_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_S_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_S_LOOP_RST_CFG_LSB, 0x0000}, + {GTYE4_CH_RXCKCAL2_X_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_X_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_X_LOOP_RST_CFG_LSB, 0x0000}, + {GTYE4_CH_RXDFE_KH_CFG2_ADDR, GTYE4_CH_RXDFE_KH_CFG2_MASK, GTYE4_CH_RXDFE_KH_CFG2_LSB, 0x0200}, + {GTYE4_CH_RXDFE_KH_CFG3_ADDR, GTYE4_CH_RXDFE_KH_CFG3_MASK, GTYE4_CH_RXDFE_KH_CFG3_LSB, 0x4101}, + {GTYE4_CH_RXPI_CFG0_ADDR, GTYE4_CH_RXPI_CFG0_MASK, GTYE4_CH_RXPI_CFG0_LSB, 0x0102}, + {GTYE4_CH_RXPI_CFG1_ADDR, GTYE4_CH_RXPI_CFG1_MASK, GTYE4_CH_RXPI_CFG1_LSB, 0x0054}, + {GTYE4_CH_RX_PROGDIV_CFG_ADDR, GTYE4_CH_RX_PROGDIV_CFG_MASK, GTYE4_CH_RX_PROGDIV_CFG_LSB, GTYE4_CH_RX_PROGDIV_CFG_33}, + {GTYE4_CH_RX_PROGDIV_RATE_ADDR, GTYE4_CH_RX_PROGDIV_RATE_MASK, GTYE4_CH_RX_PROGDIV_RATE_LSB, GTYE4_CH_RX_PROGDIV_RATE_FULL}, + {GTYE4_CH_RX_WIDEMODE_CDR_ADDR, GTYE4_CH_RX_WIDEMODE_CDR_MASK, GTYE4_CH_RX_WIDEMODE_CDR_LSB, 0x0001}, + {GTYE4_CH_RX_XMODE_SEL_ADDR, GTYE4_CH_RX_XMODE_SEL_MASK, GTYE4_CH_RX_XMODE_SEL_LSB, 0x0001}, + {GTYE4_CH_TXDRV_FREQBAND_ADDR, GTYE4_CH_TXDRV_FREQBAND_MASK, GTYE4_CH_TXDRV_FREQBAND_LSB, 0x0000}, + {GTYE4_CH_TXFE_CFG0_ADDR, GTYE4_CH_TXFE_CFG0_MASK, GTYE4_CH_TXFE_CFG0_LSB, 0x03C2}, + {GTYE4_CH_TXFE_CFG1_ADDR, GTYE4_CH_TXFE_CFG1_MASK, GTYE4_CH_TXFE_CFG1_LSB, 0x6C00}, + {GTYE4_CH_TXFE_CFG2_ADDR, GTYE4_CH_TXFE_CFG2_MASK, GTYE4_CH_TXFE_CFG2_LSB, 0x6C00}, + {GTYE4_CH_TXFE_CFG3_ADDR, GTYE4_CH_TXFE_CFG3_MASK, GTYE4_CH_TXFE_CFG3_LSB, 0x6C00}, + {GTYE4_CH_TXPI_CFG0_ADDR, GTYE4_CH_TXPI_CFG0_MASK, GTYE4_CH_TXPI_CFG0_LSB, 0x0300}, + {GTYE4_CH_TXPI_CFG1_ADDR, GTYE4_CH_TXPI_CFG1_MASK, GTYE4_CH_TXPI_CFG1_LSB, 0x1000}, + {GTYE4_CH_TXSWBST_EN_ADDR, GTYE4_CH_TXSWBST_EN_MASK, GTYE4_CH_TXSWBST_EN_LSB, 0x0000}, + {GTYE4_CH_TX_PI_BIASSET_ADDR, GTYE4_CH_TX_PI_BIASSET_MASK, GTYE4_CH_TX_PI_BIASSET_LSB, 0x0001}, + {GTYE4_CH_TX_PROGDIV_CFG_ADDR, GTYE4_CH_TX_PROGDIV_CFG_MASK, GTYE4_CH_TX_PROGDIV_CFG_LSB, GTYE4_CH_TX_PROGDIV_CFG_33}, + {GTYE4_CH_TX_PROGDIV_RATE_ADDR, GTYE4_CH_TX_PROGDIV_RATE_MASK, GTYE4_CH_TX_PROGDIV_RATE_LSB, GTYE4_CH_TX_PROGDIV_RATE_FULL}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye4_ch_preset_25g_baser_64_regs[] = { + {GTYE4_CH_CH_HSPMUX_ADDR, GTYE4_CH_CH_HSPMUX_MASK, GTYE4_CH_CH_HSPMUX_LSB, 0x9090}, + {GTYE4_CH_CKCAL1_CFG_0_ADDR, GTYE4_CH_CKCAL1_CFG_0_MASK, GTYE4_CH_CKCAL1_CFG_0_LSB, 0x4040}, + {GTYE4_CH_CKCAL1_CFG_1_ADDR, GTYE4_CH_CKCAL1_CFG_1_MASK, GTYE4_CH_CKCAL1_CFG_1_LSB, 0x1040}, + {GTYE4_CH_CKCAL2_CFG_0_ADDR, GTYE4_CH_CKCAL2_CFG_0_MASK, GTYE4_CH_CKCAL2_CFG_0_LSB, 0x4040}, + {GTYE4_CH_CKCAL2_CFG_1_ADDR, GTYE4_CH_CKCAL2_CFG_1_MASK, GTYE4_CH_CKCAL2_CFG_1_LSB, 0x0040}, + {GTYE4_CH_PREIQ_FREQ_BST_ADDR, GTYE4_CH_PREIQ_FREQ_BST_MASK, GTYE4_CH_PREIQ_FREQ_BST_LSB, 0x0003}, + {GTYE4_CH_RTX_BUF_CML_CTRL_ADDR, GTYE4_CH_RTX_BUF_CML_CTRL_MASK, GTYE4_CH_RTX_BUF_CML_CTRL_LSB, 0x0007}, + {GTYE4_CH_RTX_BUF_TERM_CTRL_ADDR, GTYE4_CH_RTX_BUF_TERM_CTRL_MASK, GTYE4_CH_RTX_BUF_TERM_CTRL_LSB, 0x0003}, + {GTYE4_CH_RXCDR_CFG2_ADDR, GTYE4_CH_RXCDR_CFG2_MASK, GTYE4_CH_RXCDR_CFG2_LSB, 0x01E9}, + {GTYE4_CH_RXCDR_CFG3_GEN2_ADDR, GTYE4_CH_RXCDR_CFG3_GEN2_MASK, GTYE4_CH_RXCDR_CFG3_GEN2_LSB, 0x0010}, + {GTYE4_CH_RXCDR_CFG3_GEN3_ADDR, GTYE4_CH_RXCDR_CFG3_GEN3_MASK, GTYE4_CH_RXCDR_CFG3_GEN3_LSB, 0x0010}, + {GTYE4_CH_RXCDR_CFG3_GEN4_ADDR, GTYE4_CH_RXCDR_CFG3_GEN4_MASK, GTYE4_CH_RXCDR_CFG3_GEN4_LSB, 0x0010}, + {GTYE4_CH_RXCDR_CFG3_ADDR, GTYE4_CH_RXCDR_CFG3_MASK, GTYE4_CH_RXCDR_CFG3_LSB, 0x0010}, + {GTYE4_CH_RXCKCAL1_IQ_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL1_IQ_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL1_IQ_LOOP_RST_CFG_LSB, 0x0004}, + {GTYE4_CH_RXCKCAL1_I_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL1_I_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL1_I_LOOP_RST_CFG_LSB, 0x0004}, + {GTYE4_CH_RXCKCAL1_Q_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL1_Q_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL1_Q_LOOP_RST_CFG_LSB, 0x0004}, + {GTYE4_CH_RXCKCAL2_DX_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_DX_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_DX_LOOP_RST_CFG_LSB, 0x0004}, + {GTYE4_CH_RXCKCAL2_D_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_D_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_D_LOOP_RST_CFG_LSB, 0x0004}, + {GTYE4_CH_RXCKCAL2_S_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_S_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_S_LOOP_RST_CFG_LSB, 0x0004}, + {GTYE4_CH_RXCKCAL2_X_LOOP_RST_CFG_ADDR, GTYE4_CH_RXCKCAL2_X_LOOP_RST_CFG_MASK, GTYE4_CH_RXCKCAL2_X_LOOP_RST_CFG_LSB, 0x0004}, + {GTYE4_CH_RXDFE_KH_CFG2_ADDR, GTYE4_CH_RXDFE_KH_CFG2_MASK, GTYE4_CH_RXDFE_KH_CFG2_LSB, 0x281C}, + {GTYE4_CH_RXDFE_KH_CFG3_ADDR, GTYE4_CH_RXDFE_KH_CFG3_MASK, GTYE4_CH_RXDFE_KH_CFG3_LSB, 0x4120}, + {GTYE4_CH_RXPI_CFG0_ADDR, GTYE4_CH_RXPI_CFG0_MASK, GTYE4_CH_RXPI_CFG0_LSB, 0x3006}, + {GTYE4_CH_RXPI_CFG1_ADDR, GTYE4_CH_RXPI_CFG1_MASK, GTYE4_CH_RXPI_CFG1_LSB, 0x0000}, + {GTYE4_CH_RX_PROGDIV_CFG_ADDR, GTYE4_CH_RX_PROGDIV_CFG_MASK, GTYE4_CH_RX_PROGDIV_CFG_LSB, GTYE4_CH_RX_PROGDIV_CFG_16P5}, + {GTYE4_CH_RX_PROGDIV_RATE_ADDR, GTYE4_CH_RX_PROGDIV_RATE_MASK, GTYE4_CH_RX_PROGDIV_RATE_LSB, GTYE4_CH_RX_PROGDIV_RATE_HALF}, + {GTYE4_CH_RX_WIDEMODE_CDR_ADDR, GTYE4_CH_RX_WIDEMODE_CDR_MASK, GTYE4_CH_RX_WIDEMODE_CDR_LSB, 0x0002}, + {GTYE4_CH_RX_XMODE_SEL_ADDR, GTYE4_CH_RX_XMODE_SEL_MASK, GTYE4_CH_RX_XMODE_SEL_LSB, 0x0000}, + {GTYE4_CH_TXDRV_FREQBAND_ADDR, GTYE4_CH_TXDRV_FREQBAND_MASK, GTYE4_CH_TXDRV_FREQBAND_LSB, 0x0003}, + {GTYE4_CH_TXFE_CFG0_ADDR, GTYE4_CH_TXFE_CFG0_MASK, GTYE4_CH_TXFE_CFG0_LSB, 0x03C6}, + {GTYE4_CH_TXFE_CFG1_ADDR, GTYE4_CH_TXFE_CFG1_MASK, GTYE4_CH_TXFE_CFG1_LSB, 0xF800}, + {GTYE4_CH_TXFE_CFG2_ADDR, GTYE4_CH_TXFE_CFG2_MASK, GTYE4_CH_TXFE_CFG2_LSB, 0xF800}, + {GTYE4_CH_TXFE_CFG3_ADDR, GTYE4_CH_TXFE_CFG3_MASK, GTYE4_CH_TXFE_CFG3_LSB, 0xF800}, + {GTYE4_CH_TXPI_CFG0_ADDR, GTYE4_CH_TXPI_CFG0_MASK, GTYE4_CH_TXPI_CFG0_LSB, 0x3000}, + {GTYE4_CH_TXPI_CFG1_ADDR, GTYE4_CH_TXPI_CFG1_MASK, GTYE4_CH_TXPI_CFG1_LSB, 0x0000}, + {GTYE4_CH_TXSWBST_EN_ADDR, GTYE4_CH_TXSWBST_EN_MASK, GTYE4_CH_TXSWBST_EN_LSB, 0x0001}, + {GTYE4_CH_TX_PI_BIASSET_ADDR, GTYE4_CH_TX_PI_BIASSET_MASK, GTYE4_CH_TX_PI_BIASSET_LSB, 0x0003}, + {GTYE4_CH_TX_PROGDIV_CFG_ADDR, GTYE4_CH_TX_PROGDIV_CFG_MASK, GTYE4_CH_TX_PROGDIV_CFG_LSB, GTYE4_CH_TX_PROGDIV_CFG_16P5}, + {GTYE4_CH_TX_PROGDIV_RATE_ADDR, GTYE4_CH_TX_PROGDIV_RATE_MASK, GTYE4_CH_TX_PROGDIV_RATE_LSB, GTYE4_CH_TX_PROGDIV_RATE_HALF}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye4_ch_preset_dfe_regs[] = { + {GTYE4_CH_RX_DEGEN_CTRL_ADDR, GTYE4_CH_RX_DEGEN_CTRL_MASK, GTYE4_CH_RX_DEGEN_CTRL_LSB, 0x0007}, + {GTYE4_CH_RX_DFE_AGC_CFG1_ADDR, GTYE4_CH_RX_DFE_AGC_CFG1_MASK, GTYE4_CH_RX_DFE_AGC_CFG1_LSB, 0x0004}, + {GTYE4_CH_RX_PMA_RSV0_ADDR, GTYE4_CH_RX_PMA_RSV0_MASK, GTYE4_CH_RX_PMA_RSV0_LSB, 0x000F}, + {GTYE4_CH_RX_SUM_DEGEN_AVTT_OVERITE_ADDR, GTYE4_CH_RX_SUM_DEGEN_AVTT_OVERITE_MASK, GTYE4_CH_RX_SUM_DEGEN_AVTT_OVERITE_LSB, 0x0001}, + {0, 0, 0, 0} +}; + +static const struct gt_reg_val gtye4_ch_preset_lpm_regs[] = { + {GTYE4_CH_RX_DEGEN_CTRL_ADDR, GTYE4_CH_RX_DEGEN_CTRL_MASK, GTYE4_CH_RX_DEGEN_CTRL_LSB, 0x0004}, + {GTYE4_CH_RX_DFE_AGC_CFG1_ADDR, GTYE4_CH_RX_DFE_AGC_CFG1_MASK, GTYE4_CH_RX_DFE_AGC_CFG1_LSB, 0x0002}, + {GTYE4_CH_RX_PMA_RSV0_ADDR, GTYE4_CH_RX_PMA_RSV0_MASK, GTYE4_CH_RX_PMA_RSV0_LSB, 0x002F}, + {GTYE4_CH_RX_SUM_DEGEN_AVTT_OVERITE_ADDR, GTYE4_CH_RX_SUM_DEGEN_AVTT_OVERITE_MASK, GTYE4_CH_RX_SUM_DEGEN_AVTT_OVERITE_LSB, 0x0000}, + {0, 0, 0, 0} +}; + +static const uint32_t gtye4_ch_presets[] = { + GT_PRESET_10G_DFE, + GT_PRESET_10G_LPM, + GT_PRESET_25G_DFE, + GT_PRESET_25G_LPM, + 0 +}; + +static int gtye4_ch_get_available_presets(struct gt_ch *ch, const uint32_t **presets) +{ + *presets = gtye4_ch_presets; + return 0; +} + +static int gtye4_ch_load_preset(struct gt_ch *ch, uint32_t preset) +{ + struct gtye4_quad_priv *priv = ch->quad->priv; + + if (preset == GT_PRESET_10G_DFE || preset == GT_PRESET_10G_LPM) + { + if (priv->qpll0_25g) + gtye4_pll_set_qpll1_pd(ch->pll, 0); + + gtye4_ch_set_tx_reset(ch, 1); + gtye4_ch_set_rx_reset(ch, 1); + + if (priv->qpll0_25g) + { + gtye4_ch_set_tx_qpll_sel(ch, 1); + gtye4_ch_set_rx_qpll_sel(ch, 1); + } + + gt_ch_reg_write_multiple(ch, gtye4_ch_preset_10g_baser_64_regs); + + if (preset == GT_PRESET_10G_DFE) + { + gt_ch_reg_write_multiple(ch, gtye4_ch_preset_dfe_regs); + gtye4_ch_set_rx_lpm_en(ch, 0); + } + else + { + gt_ch_reg_write_multiple(ch, gtye4_ch_preset_lpm_regs); + gtye4_ch_set_rx_lpm_en(ch, 1); + } + + gtye4_ch_set_tx_reset(ch, 0); + gtye4_ch_set_rx_reset(ch, 0); + + return 0; + } + + if ((preset == GT_PRESET_25G_DFE || preset == GT_PRESET_25G_LPM) && priv->qpll0_25g) + { + gtye4_ch_set_tx_reset(ch, 1); + gtye4_ch_set_rx_reset(ch, 1); + + gtye4_ch_set_tx_qpll_sel(ch, 0); + gtye4_ch_set_rx_qpll_sel(ch, 0); + + gt_ch_reg_write_multiple(ch, gtye4_ch_preset_25g_baser_64_regs); + + if (preset == GT_PRESET_25G_DFE) + { + gt_ch_reg_write_multiple(ch, gtye4_ch_preset_dfe_regs); + gtye4_ch_set_rx_lpm_en(ch, 0); + } + else + { + gt_ch_reg_write_multiple(ch, gtye4_ch_preset_lpm_regs); + gtye4_ch_set_rx_lpm_en(ch, 1); + } + + gtye4_ch_set_tx_reset(ch, 0); + gtye4_ch_set_rx_reset(ch, 0); + + return 0; + } + + return -1; +} + +static int gtye4_ch_eyescan_start(struct gt_ch *ch, struct gt_eyescan_params *params) +{ + struct gtye4_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + float ber; + + priv->eyescan_running = 0; + + gtye4_ch_get_rx_lpm_en(ch, &val); + priv->dfe_en = !val; + + gtye4_ch_get_rx_data_width(ch, &priv->rx_data_width); + gtye4_ch_get_rx_int_data_width(ch, &priv->rx_int_data_width); + + priv->prescale = 0; + + for (priv->prescale = 0; priv->prescale < 32; priv->prescale++) + { + if (((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale) >= params->target_bit_count) + break; + } + + params->target_bit_count = ((uint64_t)0xffff * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + params->h_range = 0; + + priv->h_start = params->h_start; + priv->h_stop = params->h_stop; + priv->h_step = params->h_step; + priv->v_range = params->v_range; + priv->v_start = params->v_start; + priv->v_stop = params->v_stop; + priv->v_step = params->v_step; + + gtye4_ch_set_es_control(ch, 0x00); + + gtye4_ch_set_es_prescale(ch, 4); + gtye4_ch_set_es_errdet_en(ch, 1); + + gtye4_ch_set_es_qual_mask_clear(ch); + gtye4_ch_set_es_sdata_mask_width(ch, priv->rx_int_data_width); + + gtye4_ch_set_rx_eyescan_vs_range(ch, priv->v_range); + + gtye4_ch_set_es_horz_offset(ch, 0x800); + gtye4_ch_set_rx_eyescan_vs_neg_dir(ch, 0); + gtye4_ch_set_rx_eyescan_vs_code(ch, 0); + gtye4_ch_set_rx_eyescan_vs_ut_sign(ch, 0); + + gtye4_ch_set_es_eye_scan_en(ch, 1); + + gtye4_ch_rx_pma_reset(ch); + + for (int ber_tries = 0; ber_tries < 10; ber_tries++) + { + for (int reset_tries = 0; reset_tries < 30; reset_tries++) + { + gtye4_ch_get_rx_reset_done(ch, &val); + if (val) + break; + usleep(100000); + } + + if (!val) + { + fprintf(stderr, "Error: channel stuck in reset\n"); + return -1; + } + + usleep(100000); + + // check for lock + gtye4_ch_set_es_control(ch, 0x01); + + for (int wait_tries = 0; wait_tries < 30; wait_tries++) + { + gtye4_ch_get_es_control_status(ch, &val); + if (val & 1) + break; + usleep(100000); + } + + if (!(val & 1)) + { + fprintf(stderr, "Error: eye scan did not finish (%d)\n", val); + return -1; + } + + gtye4_ch_set_es_control(ch, 0x00); + + gtye4_ch_get_es_error_count(ch, &error_count); + gtye4_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+4); + + ber = (float)error_count / (float)bit_count; + + if (ber < 0.01) + break; + + printf("High BER (%02f), resetting eye scan logic\n", ber); + + gtye4_ch_set_es_horz_offset(ch, 0x880); + gtye4_ch_set_eyescan_reset(ch, 1); + gtye4_ch_set_es_horz_offset(ch, 0x800); + gtye4_ch_set_eyescan_reset(ch, 0); + } + + if (ber > 0.01) + { + fprintf(stderr, "Error: High BER, alignment failed\n"); + return -1; + } + + // set up for measurement + priv->h_offset = priv->h_start; + priv->v_offset = priv->v_start; + priv->ut_sign = 0; + + gtye4_ch_set_es_control(ch, 0x00); + gtye4_ch_set_es_prescale(ch, priv->prescale); + gtye4_ch_set_es_errdet_en(ch, 1); + gtye4_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | 0x800); + gtye4_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gtye4_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + gtye4_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + // start measurement + gtye4_ch_set_es_control(ch, 0x01); + + priv->eyescan_running = 1; + + return 0; +} + +static int gtye4_ch_eyescan_step(struct gt_ch *ch, struct gt_eyescan_point *point) +{ + struct gtye4_ch_priv *priv = ch->priv; + uint32_t val; + + uint32_t error_count; + uint32_t sample_count; + uint64_t bit_count; + + int restart = 0; + + if (!priv->eyescan_running) + return 0; + + gtye4_ch_get_es_control_status(ch, &val); + if (!(val & 1)) + return 2; + + gtye4_ch_set_es_control(ch, 0x00); + + gtye4_ch_get_es_error_count(ch, &error_count); + gtye4_ch_get_es_sample_count(ch, &sample_count); + bit_count = ((uint64_t)sample_count * (uint64_t)priv->rx_int_data_width) << (1+priv->prescale); + + point->error_count = error_count; + point->bit_count = bit_count; + point->x = priv->h_offset; + point->y = priv->v_offset; + point->ut_sign = priv->ut_sign; + + restart = 0; + + if (!priv->ut_sign && priv->dfe_en) + { + priv->ut_sign = 1; + restart = 1; + } + else + { + priv->ut_sign = 0; + } + + gtye4_ch_set_rx_eyescan_vs_ut_sign(ch, priv->ut_sign); + + if (restart) + { + gtye4_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->v_offset < priv->v_stop) + { + priv->v_offset += priv->v_step; + restart = 1; + } + else + { + priv->v_offset = priv->v_start; + } + + gtye4_ch_set_rx_eyescan_vs_neg_dir(ch, (priv->v_offset < 0)); + gtye4_ch_set_rx_eyescan_vs_code(ch, priv->v_offset < 0 ? -priv->v_offset : priv->v_offset); + + if (restart) + { + gtye4_ch_set_es_control(ch, 0x01); + return 1; + } + + if (priv->h_offset < priv->h_stop) + { + priv->h_offset += priv->h_step; + restart = 1; + } + else + { + // done + priv->eyescan_running = 0; + return 1; + } + + gtye4_ch_set_es_horz_offset(ch, (priv->h_offset & 0x7ff) | 0x800); + + if (restart) + { + gtye4_ch_set_es_control(ch, 0x01); + return 1; + } + + priv->eyescan_running = 0; + return 0; +} + +const struct gt_ch_ops gtye4_gt_ch_ops = { + .get_tx_reset = gtye4_ch_get_tx_reset, + .set_tx_reset = gtye4_ch_set_tx_reset, + .tx_reset = gtye4_ch_tx_reset, + .get_rx_reset = gtye4_ch_get_rx_reset, + .set_rx_reset = gtye4_ch_set_rx_reset, + .rx_reset = gtye4_ch_rx_reset, + .get_tx_data_width = gtye4_ch_get_tx_data_width, + .get_tx_int_data_width = gtye4_ch_get_tx_int_data_width, + .get_rx_data_width = gtye4_ch_get_rx_data_width, + .get_rx_int_data_width = gtye4_ch_get_rx_int_data_width, + .get_available_presets = gtye4_ch_get_available_presets, + .load_preset = gtye4_ch_load_preset, + .eyescan_start = gtye4_ch_eyescan_start, + .eyescan_step = gtye4_ch_eyescan_step +}; + +static int gtye4_ch_init(struct gt_ch *ch) +{ + struct gtye4_ch_priv *priv = calloc(1, sizeof(struct gtye4_ch_priv)); + if (!priv) + return -1; + + ch->priv = priv; + + return 0; +} + +static int gtye4_quad_init(struct gt_quad *quad) +{ + uint32_t val; + struct gtye4_quad_priv *priv = calloc(1, sizeof(struct gtye4_quad_priv)); + if (!priv) + return -1; + + quad->priv = priv; + quad->type = "GTYE4"; + + gtye4_pll_get_qpll0clkout_rate(&quad->pll, &val); + priv->qpll0_25g = val == GTYE4_COM_QPLL0CLKOUT_RATE_FULL; + + for (int n = 0; n < quad->ch_count; n++) + { + quad->ch[n].quad = quad; + quad->ch[n].pll = &quad->pll; + quad->ch[n].ops = >ye4_gt_ch_ops; + quad->ch[n].index = n; + + gtye4_ch_init(&quad->ch[n]); + } + + return 0; +} + +const struct gt_quad_ops gtye4_gt_quad_ops = { + .init = gtye4_quad_init +}; diff --git a/utils/xcvr_gtye4.h b/utils/xcvr_gtye4.h new file mode 100644 index 000000000..cda18cf4e --- /dev/null +++ b/utils/xcvr_gtye4.h @@ -0,0 +1,414 @@ +/* + +Copyright 2022, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +*/ + +#ifndef XCVR_GTYE4_H +#define XCVR_GTYE4_H + +#include "xcvr_gt.h" +#include "gt/gtye4_regs.h" + +// signals +#define GTYE4_COM_QPLL0_RESET_ADDR 0x10000 +#define GTYE4_COM_QPLL0_RESET_MSB 0 +#define GTYE4_COM_QPLL0_RESET_LSB 0 +#define GTYE4_COM_QPLL0_RESET_MASK BIT_MASK(GTYE4_COM_QPLL0_RESET_MSB, GTYE4_COM_QPLL0_RESET_LSB) +#define GTYE4_COM_QPLL0_LOCK_ADDR 0x10000 +#define GTYE4_COM_QPLL0_LOCK_MSB 8 +#define GTYE4_COM_QPLL0_LOCK_LSB 8 +#define GTYE4_COM_QPLL0_LOCK_MASK BIT_MASK(GTYE4_COM_QPLL0_LOCK_MSB, GTYE4_COM_QPLL0_LOCK_LSB) +#define GTYE4_COM_QPLL0_PD_ADDR 0x10001 +#define GTYE4_COM_QPLL0_PD_MSB 0 +#define GTYE4_COM_QPLL0_PD_LSB 0 +#define GTYE4_COM_QPLL0_PD_MASK BIT_MASK(GTYE4_COM_QPLL0_PD_MSB, GTYE4_COM_QPLL0_PD_LSB) +#define GTYE4_COM_QPLL1_RESET_ADDR 0x11000 +#define GTYE4_COM_QPLL1_RESET_MSB 0 +#define GTYE4_COM_QPLL1_RESET_LSB 0 +#define GTYE4_COM_QPLL1_RESET_MASK BIT_MASK(GTYE4_COM_QPLL0_RESET_MSB, GTYE4_COM_QPLL0_RESET_LSB) +#define GTYE4_COM_QPLL1_LOCK_ADDR 0x11000 +#define GTYE4_COM_QPLL1_LOCK_MSB 8 +#define GTYE4_COM_QPLL1_LOCK_LSB 8 +#define GTYE4_COM_QPLL1_LOCK_MASK BIT_MASK(GTYE4_COM_QPLL0_LOCK_MSB, GTYE4_COM_QPLL0_LOCK_LSB) +#define GTYE4_COM_QPLL1_PD_ADDR 0x11001 +#define GTYE4_COM_QPLL1_PD_MSB 0 +#define GTYE4_COM_QPLL1_PD_LSB 0 +#define GTYE4_COM_QPLL1_PD_MASK BIT_MASK(GTYE4_COM_QPLL1_PD_MSB, GTYE4_COM_QPLL1_PD_LSB) + +#define GTYE4_CH_TX_RESET_ADDR 0x10000 +#define GTYE4_CH_TX_RESET_MSB 0 +#define GTYE4_CH_TX_RESET_LSB 0 +#define GTYE4_CH_TX_RESET_MASK BIT_MASK(GTYE4_CH_TX_RESET_MSB, GTYE4_CH_TX_RESET_LSB) +#define GTYE4_CH_TX_PMA_RESET_ADDR 0x10000 +#define GTYE4_CH_TX_PMA_RESET_MSB 1 +#define GTYE4_CH_TX_PMA_RESET_LSB 1 +#define GTYE4_CH_TX_PMA_RESET_MASK BIT_MASK(GTYE4_CH_TX_PMA_RESET_MSB, GTYE4_CH_TX_PMA_RESET_LSB) +#define GTYE4_CH_TX_PCS_RESET_ADDR 0x10000 +#define GTYE4_CH_TX_PCS_RESET_MSB 2 +#define GTYE4_CH_TX_PCS_RESET_LSB 2 +#define GTYE4_CH_TX_PCS_RESET_MASK BIT_MASK(GTYE4_CH_TX_PCS_RESET_MSB, GTYE4_CH_TX_PCS_RESET_LSB) +#define GTYE4_CH_TX_RESET_DONE_ADDR 0x10000 +#define GTYE4_CH_TX_RESET_DONE_MSB 8 +#define GTYE4_CH_TX_RESET_DONE_LSB 8 +#define GTYE4_CH_TX_RESET_DONE_MASK BIT_MASK(GTYE4_CH_TX_RESET_DONE_MSB, GTYE4_CH_TX_RESET_DONE_LSB) +#define GTYE4_CH_TX_GT_RESET_DONE_ADDR 0x10000 +#define GTYE4_CH_TX_GT_RESET_DONE_MSB 9 +#define GTYE4_CH_TX_GT_RESET_DONE_LSB 9 +#define GTYE4_CH_TX_GT_RESET_DONE_MASK BIT_MASK(GTYE4_CH_TX_GT_RESET_DONE_MSB, GTYE4_CH_TX_GT_RESET_DONE_LSB) +#define GTYE4_CH_TX_PMA_RESET_DONE_ADDR 0x10000 +#define GTYE4_CH_TX_PMA_RESET_DONE_MSB 10 +#define GTYE4_CH_TX_PMA_RESET_DONE_LSB 10 +#define GTYE4_CH_TX_PMA_RESET_DONE_MASK BIT_MASK(GTYE4_CH_TX_PMA_RESET_DONE_MSB, GTYE4_CH_TX_PMA_RESET_DONE_LSB) +#define GTYE4_CH_TX_PRGDIV_RESET_DONE_ADDR 0x10000 +#define GTYE4_CH_TX_PRGDIV_RESET_DONE_MSB 11 +#define GTYE4_CH_TX_PRGDIV_RESET_DONE_LSB 11 +#define GTYE4_CH_TX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTYE4_CH_TX_PRGDIV_RESET_DONE_MSB, GTYE4_CH_TX_PRGDIV_RESET_DONE_LSB) +#define GTYE4_CH_TX_USRCLK_ACT_ADDR 0x10000 +#define GTYE4_CH_TX_USRCLK_ACT_MSB 12 +#define GTYE4_CH_TX_USRCLK_ACT_LSB 12 +#define GTYE4_CH_TX_USRCLK_ACT_MASK BIT_MASK(GTYE4_CH_TX_USRCLK_ACT_MSB, GTYE4_CH_TX_USRCLK_ACT_LSB) +#define GTYE4_CH_TX_PD_ADDR 0x10001 +#define GTYE4_CH_TX_PD_MSB 0 +#define GTYE4_CH_TX_PD_LSB 0 +#define GTYE4_CH_TX_PD_MASK BIT_MASK(GTYE4_CH_TX_PD_MSB, GTYE4_CH_TX_PD_LSB) +#define GTYE4_CH_TX_QPLL_SEL_ADDR 0x10001 +#define GTYE4_CH_TX_QPLL_SEL_MSB 1 +#define GTYE4_CH_TX_QPLL_SEL_LSB 1 +#define GTYE4_CH_TX_QPLL_SEL_MASK BIT_MASK(GTYE4_CH_TX_QPLL_SEL_MSB, GTYE4_CH_TX_QPLL_SEL_LSB) +#define GTYE4_CH_TX_POLARITY_ADDR 0x10010 +#define GTYE4_CH_TX_POLARITY_MSB 0 +#define GTYE4_CH_TX_POLARITY_LSB 0 +#define GTYE4_CH_TX_POLARITY_MASK BIT_MASK(GTYE4_CH_TX_POLARITY_MSB, GTYE4_CH_TX_POLARITY_LSB) +#define GTYE4_CH_TX_ELECIDLE_ADDR 0x10010 +#define GTYE4_CH_TX_ELECIDLE_MSB 1 +#define GTYE4_CH_TX_ELECIDLE_LSB 1 +#define GTYE4_CH_TX_ELECIDLE_MASK BIT_MASK(GTYE4_CH_TX_ELECIDLE_MSB, GTYE4_CH_TX_ELECIDLE_LSB) +#define GTYE4_CH_TX_INHIBIT_ADDR 0x10010 +#define GTYE4_CH_TX_INHIBIT_MSB 2 +#define GTYE4_CH_TX_INHIBIT_LSB 2 +#define GTYE4_CH_TX_INHIBIT_MASK BIT_MASK(GTYE4_CH_TX_INHIBIT_MSB, GTYE4_CH_TX_INHIBIT_LSB) +#define GTYE4_CH_TX_DIFFCTRL_ADDR 0x10011 +#define GTYE4_CH_TX_DIFFCTRL_MSB 4 +#define GTYE4_CH_TX_DIFFCTRL_LSB 0 +#define GTYE4_CH_TX_DIFFCTRL_MASK BIT_MASK(GTYE4_CH_TX_DIFFCTRL_MSB, GTYE4_CH_TX_DIFFCTRL_LSB) +#define GTYE4_CH_TX_MAINCURSOR_ADDR 0x10012 +#define GTYE4_CH_TX_MAINCURSOR_MSB 6 +#define GTYE4_CH_TX_MAINCURSOR_LSB 0 +#define GTYE4_CH_TX_MAINCURSOR_MASK BIT_MASK(GTYE4_CH_TX_MAINCURSOR_MSB, GTYE4_CH_TX_MAINCURSOR_LSB) +#define GTYE4_CH_TX_PRECURSOR_ADDR 0x10013 +#define GTYE4_CH_TX_PRECURSOR_MSB 4 +#define GTYE4_CH_TX_PRECURSOR_LSB 0 +#define GTYE4_CH_TX_PRECURSOR_MASK BIT_MASK(GTYE4_CH_TX_PRECURSOR_MSB, GTYE4_CH_TX_PRECURSOR_LSB) +#define GTYE4_CH_TX_POSTCURSOR_ADDR 0x10014 +#define GTYE4_CH_TX_POSTCURSOR_MSB 4 +#define GTYE4_CH_TX_POSTCURSOR_LSB 0 +#define GTYE4_CH_TX_POSTCURSOR_MASK BIT_MASK(GTYE4_CH_TX_POSTCURSOR_MSB, GTYE4_CH_TX_POSTCURSOR_LSB) +#define GTYE4_CH_TX_PRBS_SEL_ADDR 0x10040 +#define GTYE4_CH_TX_PRBS_SEL_MSB 3 +#define GTYE4_CH_TX_PRBS_SEL_LSB 0 +#define GTYE4_CH_TX_PRBS_SEL_MASK BIT_MASK(GTYE4_CH_TX_PRBS_SEL_MSB, GTYE4_CH_TX_PRBS_SEL_LSB) +#define GTYE4_CH_TX_PRBS_FORCERR_ADDR 0x10040 +#define GTYE4_CH_TX_PRBS_FORCERR_MSB 15 +#define GTYE4_CH_TX_PRBS_FORCERR_LSB 0 +#define GTYE4_CH_TX_PRBS_FORCERR_MASK BIT_MASK(GTYE4_CH_TX_PRBS_FORCERR_MSB, GTYE4_CH_TX_PRBS_FORCERR_LSB) +#define GTYE4_CH_RX_RESET_ADDR 0x11000 +#define GTYE4_CH_RX_RESET_MSB 0 +#define GTYE4_CH_RX_RESET_LSB 0 +#define GTYE4_CH_RX_RESET_MASK BIT_MASK(GTYE4_CH_RX_RESET_MSB, GTYE4_CH_RX_RESET_LSB) +#define GTYE4_CH_RX_PMA_RESET_ADDR 0x11000 +#define GTYE4_CH_RX_PMA_RESET_MSB 1 +#define GTYE4_CH_RX_PMA_RESET_LSB 1 +#define GTYE4_CH_RX_PMA_RESET_MASK BIT_MASK(GTYE4_CH_RX_PMA_RESET_MSB, GTYE4_CH_RX_PMA_RESET_LSB) +#define GTYE4_CH_RX_PCS_RESET_ADDR 0x11000 +#define GTYE4_CH_RX_PCS_RESET_MSB 2 +#define GTYE4_CH_RX_PCS_RESET_LSB 2 +#define GTYE4_CH_RX_PCS_RESET_MASK BIT_MASK(GTYE4_CH_RX_PCS_RESET_MSB, GTYE4_CH_RX_PCS_RESET_LSB) +#define GTYE4_CH_RX_DFE_LPM_RESET_ADDR 0x11000 +#define GTYE4_CH_RX_DFE_LPM_RESET_MSB 3 +#define GTYE4_CH_RX_DFE_LPM_RESET_LSB 3 +#define GTYE4_CH_RX_DFE_LPM_RESET_MASK BIT_MASK(GTYE4_CH_RX_DFE_LPM_RESET_MSB, GTYE4_CH_RX_DFE_LPM_RESET_LSB) +#define GTYE4_CH_EYESCAN_RESET_ADDR 0x11000 +#define GTYE4_CH_EYESCAN_RESET_MSB 4 +#define GTYE4_CH_EYESCAN_RESET_LSB 4 +#define GTYE4_CH_EYESCAN_RESET_MASK BIT_MASK(GTYE4_CH_EYESCAN_RESET_MSB, GTYE4_CH_EYESCAN_RESET_LSB) +#define GTYE4_CH_RX_RESET_DONE_ADDR 0x11000 +#define GTYE4_CH_RX_RESET_DONE_MSB 8 +#define GTYE4_CH_RX_RESET_DONE_LSB 8 +#define GTYE4_CH_RX_RESET_DONE_MASK BIT_MASK(GTYE4_CH_RX_RESET_DONE_MSB, GTYE4_CH_RX_RESET_DONE_LSB) +#define GTYE4_CH_RX_GT_RESET_DONE_ADDR 0x11000 +#define GTYE4_CH_RX_GT_RESET_DONE_MSB 9 +#define GTYE4_CH_RX_GT_RESET_DONE_LSB 9 +#define GTYE4_CH_RX_GT_RESET_DONE_MASK BIT_MASK(GTYE4_CH_RX_GT_RESET_DONE_MSB, GTYE4_CH_RX_GT_RESET_DONE_LSB) +#define GTYE4_CH_RX_PMA_RESET_DONE_ADDR 0x11000 +#define GTYE4_CH_RX_PMA_RESET_DONE_MSB 10 +#define GTYE4_CH_RX_PMA_RESET_DONE_LSB 10 +#define GTYE4_CH_RX_PMA_RESET_DONE_MASK BIT_MASK(GTYE4_CH_RX_PMA_RESET_DONE_MSB, GTYE4_CH_RX_PMA_RESET_DONE_LSB) +#define GTYE4_CH_RX_PRGDIV_RESET_DONE_ADDR 0x11000 +#define GTYE4_CH_RX_PRGDIV_RESET_DONE_MSB 11 +#define GTYE4_CH_RX_PRGDIV_RESET_DONE_LSB 11 +#define GTYE4_CH_RX_PRGDIV_RESET_DONE_MASK BIT_MASK(GTYE4_CH_RX_PRGDIV_RESET_DONE_MSB, GTYE4_CH_RX_PRGDIV_RESET_DONE_LSB) +#define GTYE4_CH_RX_USRCLK_ACT_ADDR 0x11000 +#define GTYE4_CH_RX_USRCLK_ACT_MSB 12 +#define GTYE4_CH_RX_USRCLK_ACT_LSB 12 +#define GTYE4_CH_RX_USRCLK_ACT_MASK BIT_MASK(GTYE4_CH_RX_USRCLK_ACT_MSB, GTYE4_CH_RX_USRCLK_ACT_LSB) +#define GTYE4_CH_RX_PD_ADDR 0x11001 +#define GTYE4_CH_RX_PD_MSB 0 +#define GTYE4_CH_RX_PD_LSB 0 +#define GTYE4_CH_RX_PD_MASK BIT_MASK(GTYE4_CH_RX_PD_MSB, GTYE4_CH_RX_PD_LSB) +#define GTYE4_CH_RX_QPLL_SEL_ADDR 0x11001 +#define GTYE4_CH_RX_QPLL_SEL_MSB 1 +#define GTYE4_CH_RX_QPLL_SEL_LSB 1 +#define GTYE4_CH_RX_QPLL_SEL_MASK BIT_MASK(GTYE4_CH_RX_QPLL_SEL_MSB, GTYE4_CH_RX_QPLL_SEL_LSB) +#define GTYE4_CH_LOOPBACK_ADDR 0x11002 +#define GTYE4_CH_LOOPBACK_MSB 2 +#define GTYE4_CH_LOOPBACK_LSB 0 +#define GTYE4_CH_LOOPBACK_MASK BIT_MASK(GTYE4_CH_LOOPBACK_MSB, GTYE4_CH_LOOPBACK_LSB) +#define GTYE4_CH_RX_POLARITY_ADDR 0x11010 +#define GTYE4_CH_RX_POLARITY_MSB 0 +#define GTYE4_CH_RX_POLARITY_LSB 0 +#define GTYE4_CH_RX_POLARITY_MASK BIT_MASK(GTYE4_CH_RX_POLARITY_MSB, GTYE4_CH_RX_POLARITY_LSB) +#define GTYE4_CH_RX_CDR_HOLD_ADDR 0x11020 +#define GTYE4_CH_RX_CDR_HOLD_MSB 0 +#define GTYE4_CH_RX_CDR_HOLD_LSB 0 +#define GTYE4_CH_RX_CDR_HOLD_MASK BIT_MASK(GTYE4_CH_RX_CDR_HOLD_MSB, GTYE4_CH_RX_CDR_HOLD_LSB) +#define GTYE4_CH_RX_CDR_LOCK_ADDR 0x11020 +#define GTYE4_CH_RX_CDR_LOCK_MSB 8 +#define GTYE4_CH_RX_CDR_LOCK_LSB 8 +#define GTYE4_CH_RX_CDR_LOCK_MASK BIT_MASK(GTYE4_CH_RX_CDR_LOCK_MSB, GTYE4_CH_RX_CDR_LOCK_LSB) +#define GTYE4_CH_RX_LPM_EN_ADDR 0x11024 +#define GTYE4_CH_RX_LPM_EN_MSB 0 +#define GTYE4_CH_RX_LPM_EN_LSB 0 +#define GTYE4_CH_RX_LPM_EN_MASK BIT_MASK(GTYE4_CH_RX_LPM_EN_MSB, GTYE4_CH_RX_LPM_EN_LSB) +#define GTYE4_CH_RX_DMONITOR_ADDR 0x11028 +#define GTYE4_CH_RX_DMONITOR_MSB 7 +#define GTYE4_CH_RX_DMONITOR_LSB 0 +#define GTYE4_CH_RX_DMONITOR_MASK BIT_MASK(GTYE4_CH_RX_DMONITOR_MSB, GTYE4_CH_RX_DMONITOR_LSB) +#define GTYE4_CH_RX_PRBS_SEL_ADDR 0x11040 +#define GTYE4_CH_RX_PRBS_SEL_MSB 3 +#define GTYE4_CH_RX_PRBS_SEL_LSB 0 +#define GTYE4_CH_RX_PRBS_SEL_MASK BIT_MASK(GTYE4_CH_RX_PRBS_SEL_MSB, GTYE4_CH_RX_PRBS_SEL_LSB) +#define GTYE4_CH_RX_PRBS_CNT_RESET_ADDR 0x11041 +#define GTYE4_CH_RX_PRBS_CNT_RESET_MSB 0 +#define GTYE4_CH_RX_PRBS_CNT_RESET_LSB 0 +#define GTYE4_CH_RX_PRBS_CNT_RESET_MASK BIT_MASK(GTYE4_CH_RX_PRBS_CNT_RESET_MSB, GTYE4_CH_RX_PRBS_CNT_RESET_LSB) +#define GTYE4_CH_RX_PRBS_LOCKED_ADDR 0x11041 +#define GTYE4_CH_RX_PRBS_LOCKED_MSB 8 +#define GTYE4_CH_RX_PRBS_LOCKED_LSB 8 +#define GTYE4_CH_RX_PRBS_LOCKED_MASK BIT_MASK(GTYE4_CH_RX_PRBS_LOCKED_MSB, GTYE4_CH_RX_PRBS_LOCKED_LSB) +#define GTYE4_CH_RX_PRBS_ERROR_ADDR 0x11041 +#define GTYE4_CH_RX_PRBS_ERROR_MSB 9 +#define GTYE4_CH_RX_PRBS_ERROR_LSB 9 +#define GTYE4_CH_RX_PRBS_ERROR_MASK BIT_MASK(GTYE4_CH_RX_PRBS_ERROR_MSB, GTYE4_CH_RX_PRBS_ERROR_LSB) + + +def_gt_pll_masked_reg_rw16(gtye4, qpll0_reset, GTYE4_COM_QPLL0_RESET_ADDR, GTYE4_COM_QPLL0_RESET_MASK, GTYE4_COM_QPLL0_RESET_LSB); +int gtye4_pll_qpll0_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gtye4, qpll0_lock, GTYE4_COM_QPLL0_LOCK_ADDR, GTYE4_COM_QPLL0_LOCK_MASK, GTYE4_COM_QPLL0_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_pd, GTYE4_COM_QPLL0_PD_ADDR, GTYE4_COM_QPLL0_PD_MASK, GTYE4_COM_QPLL0_PD_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_reset, GTYE4_COM_QPLL1_RESET_ADDR, GTYE4_COM_QPLL1_RESET_MASK, GTYE4_COM_QPLL1_RESET_LSB); +int gtye4_pll_qpll1_reset(struct gt_pll *pll); +def_gt_pll_masked_reg_read16(gtye4, qpll1_lock, GTYE4_COM_QPLL1_LOCK_ADDR, GTYE4_COM_QPLL1_LOCK_MASK, GTYE4_COM_QPLL1_LOCK_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_pd, GTYE4_COM_QPLL1_PD_ADDR, GTYE4_COM_QPLL1_PD_MASK, GTYE4_COM_QPLL1_PD_LSB); + +def_gt_ch_masked_reg_rw16(gtye4, tx_reset, GTYE4_CH_TX_RESET_ADDR, GTYE4_CH_TX_RESET_MASK, GTYE4_CH_TX_RESET_LSB); +int gtye4_ch_tx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye4, tx_pma_reset, GTYE4_CH_TX_PMA_RESET_ADDR, GTYE4_CH_TX_PMA_RESET_MASK, GTYE4_CH_TX_PMA_RESET_LSB); +int gtye4_ch_tx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye4, tx_pcs_reset, GTYE4_CH_TX_PCS_RESET_ADDR, GTYE4_CH_TX_PCS_RESET_MASK, GTYE4_CH_TX_PCS_RESET_LSB); +int gtye4_ch_tx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gtye4, tx_reset_done, GTYE4_CH_TX_RESET_DONE_ADDR, GTYE4_CH_TX_RESET_DONE_MASK, GTYE4_CH_TX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, tx_gt_reset_done, GTYE4_CH_TX_GT_RESET_DONE_ADDR, GTYE4_CH_TX_GT_RESET_DONE_MASK, GTYE4_CH_TX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, tx_pma_reset_done, GTYE4_CH_TX_PMA_RESET_DONE_ADDR, GTYE4_CH_TX_PMA_RESET_DONE_MASK, GTYE4_CH_TX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, tx_prgdiv_reset_done, GTYE4_CH_TX_PRGDIV_RESET_DONE_ADDR, GTYE4_CH_TX_PRGDIV_RESET_DONE_MASK, GTYE4_CH_TX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, tx_usrclk_act, GTYE4_CH_TX_USRCLK_ACT_ADDR, GTYE4_CH_TX_USRCLK_ACT_MASK, GTYE4_CH_TX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_pd, GTYE4_CH_TX_PD_ADDR, GTYE4_CH_TX_PD_MASK, GTYE4_CH_TX_PD_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_qpll_sel, GTYE4_CH_TX_QPLL_SEL_ADDR, GTYE4_CH_TX_QPLL_SEL_MASK, GTYE4_CH_TX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_polarity, GTYE4_CH_TX_POLARITY_ADDR, GTYE4_CH_TX_POLARITY_MASK, GTYE4_CH_TX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_elecidle, GTYE4_CH_TX_ELECIDLE_ADDR, GTYE4_CH_TX_ELECIDLE_MASK, GTYE4_CH_TX_ELECIDLE_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_inhibit, GTYE4_CH_TX_INHIBIT_ADDR, GTYE4_CH_TX_INHIBIT_MASK, GTYE4_CH_TX_INHIBIT_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_diffctrl, GTYE4_CH_TX_DIFFCTRL_ADDR, GTYE4_CH_TX_DIFFCTRL_MASK, GTYE4_CH_TX_DIFFCTRL_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_maincursor, GTYE4_CH_TX_MAINCURSOR_ADDR, GTYE4_CH_TX_MAINCURSOR_MASK, GTYE4_CH_TX_MAINCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_precursor, GTYE4_CH_TX_PRECURSOR_ADDR, GTYE4_CH_TX_PRECURSOR_MASK, GTYE4_CH_TX_PRECURSOR_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_postcursor, GTYE4_CH_TX_POSTCURSOR_ADDR, GTYE4_CH_TX_POSTCURSOR_MASK, GTYE4_CH_TX_POSTCURSOR_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_prbs_sel, GTYE4_CH_TX_PRBS_SEL_ADDR, GTYE4_CH_TX_PRBS_SEL_MASK, GTYE4_CH_TX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye4, tx_prbs_forcerr, GTYE4_CH_TX_PRBS_FORCERR_ADDR, GTYE4_CH_TX_PRBS_FORCERR_MASK, GTYE4_CH_TX_PRBS_FORCERR_LSB); + +def_gt_ch_masked_reg_rw16(gtye4, rx_reset, GTYE4_CH_RX_RESET_ADDR, GTYE4_CH_RX_RESET_MASK, GTYE4_CH_RX_RESET_LSB); +int gtye4_ch_rx_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye4, rx_pma_reset, GTYE4_CH_RX_PMA_RESET_ADDR, GTYE4_CH_RX_PMA_RESET_MASK, GTYE4_CH_RX_PMA_RESET_LSB); +int gtye4_ch_rx_pma_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye4, rx_pcs_reset, GTYE4_CH_RX_PCS_RESET_ADDR, GTYE4_CH_RX_PCS_RESET_MASK, GTYE4_CH_RX_PCS_RESET_LSB); +int gtye4_ch_rx_pcs_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye4, rx_dfe_lpm_reset, GTYE4_CH_RX_DFE_LPM_RESET_ADDR, GTYE4_CH_RX_DFE_LPM_RESET_MASK, GTYE4_CH_RX_DFE_LPM_RESET_LSB); +int gtye4_ch_rx_dfe_lpm_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_rw16(gtye4, eyescan_reset, GTYE4_CH_EYESCAN_RESET_ADDR, GTYE4_CH_EYESCAN_RESET_MASK, GTYE4_CH_EYESCAN_RESET_LSB); +int gtye4_ch_eyescan_reset(struct gt_ch *ch); +def_gt_ch_masked_reg_read16(gtye4, rx_reset_done, GTYE4_CH_RX_RESET_DONE_ADDR, GTYE4_CH_RX_RESET_DONE_MASK, GTYE4_CH_RX_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_gt_reset_done, GTYE4_CH_RX_GT_RESET_DONE_ADDR, GTYE4_CH_RX_GT_RESET_DONE_MASK, GTYE4_CH_RX_GT_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_pma_reset_done, GTYE4_CH_RX_PMA_RESET_DONE_ADDR, GTYE4_CH_RX_PMA_RESET_DONE_MASK, GTYE4_CH_RX_PMA_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_prgdiv_reset_done, GTYE4_CH_RX_PRGDIV_RESET_DONE_ADDR, GTYE4_CH_RX_PRGDIV_RESET_DONE_MASK, GTYE4_CH_RX_PRGDIV_RESET_DONE_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_usrclk_act, GTYE4_CH_RX_USRCLK_ACT_ADDR, GTYE4_CH_RX_USRCLK_ACT_MASK, GTYE4_CH_RX_USRCLK_ACT_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_pd, GTYE4_CH_RX_PD_ADDR, GTYE4_CH_RX_PD_MASK, GTYE4_CH_RX_PD_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_qpll_sel, GTYE4_CH_RX_QPLL_SEL_ADDR, GTYE4_CH_RX_QPLL_SEL_MASK, GTYE4_CH_RX_QPLL_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye4, loopback, GTYE4_CH_LOOPBACK_ADDR, GTYE4_CH_LOOPBACK_MASK, GTYE4_CH_LOOPBACK_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_polarity, GTYE4_CH_RX_POLARITY_ADDR, GTYE4_CH_RX_POLARITY_MASK, GTYE4_CH_RX_POLARITY_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_cdr_hold, GTYE4_CH_RX_CDR_HOLD_ADDR, GTYE4_CH_RX_CDR_HOLD_MASK, GTYE4_CH_RX_CDR_HOLD_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_cdr_lock, GTYE4_CH_RX_CDR_LOCK_ADDR, GTYE4_CH_RX_CDR_LOCK_MASK, GTYE4_CH_RX_CDR_LOCK_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_lpm_en, GTYE4_CH_RX_LPM_EN_ADDR, GTYE4_CH_RX_LPM_EN_MASK, GTYE4_CH_RX_LPM_EN_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_dmonitor, GTYE4_CH_RX_DMONITOR_ADDR, GTYE4_CH_RX_DMONITOR_MASK, GTYE4_CH_RX_DMONITOR_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_prbs_sel, GTYE4_CH_RX_PRBS_SEL_ADDR, GTYE4_CH_RX_PRBS_SEL_MASK, GTYE4_CH_RX_PRBS_SEL_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_prbs_cnt_reset, GTYE4_CH_RX_PRBS_CNT_RESET_ADDR, GTYE4_CH_RX_PRBS_CNT_RESET_MASK, GTYE4_CH_RX_PRBS_CNT_RESET_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_prbs_locked, GTYE4_CH_RX_PRBS_LOCKED_ADDR, GTYE4_CH_RX_PRBS_LOCKED_MASK, GTYE4_CH_RX_PRBS_LOCKED_LSB); +def_gt_ch_masked_reg_read16(gtye4, rx_prbs_error, GTYE4_CH_RX_PRBS_ERROR_ADDR, GTYE4_CH_RX_PRBS_ERROR_MASK, GTYE4_CH_RX_PRBS_ERROR_LSB); + +// common +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cfg0, GTYE4_COM_QPLL0_CFG0_ADDR, GTYE4_COM_QPLL0_CFG0_MASK, GTYE4_COM_QPLL0_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, common_cfg0, GTYE4_COM_COMMON_CFG0_ADDR, GTYE4_COM_COMMON_CFG0_MASK, GTYE4_COM_COMMON_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ppf0_cfg, GTYE4_COM_PPF0_CFG_ADDR, GTYE4_COM_PPF0_CFG_MASK, GTYE4_COM_PPF0_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0clkout_rate, GTYE4_COM_QPLL0CLKOUT_RATE_ADDR, GTYE4_COM_QPLL0CLKOUT_RATE_MASK, GTYE4_COM_QPLL0CLKOUT_RATE_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cfg1, GTYE4_COM_QPLL0_CFG1_ADDR, GTYE4_COM_QPLL0_CFG1_MASK, GTYE4_COM_QPLL0_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cfg2, GTYE4_COM_QPLL0_CFG2_ADDR, GTYE4_COM_QPLL0_CFG2_MASK, GTYE4_COM_QPLL0_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_lock_cfg, GTYE4_COM_QPLL0_LOCK_CFG_ADDR, GTYE4_COM_QPLL0_LOCK_CFG_MASK, GTYE4_COM_QPLL0_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_init_cfg0, GTYE4_COM_QPLL0_INIT_CFG0_ADDR, GTYE4_COM_QPLL0_INIT_CFG0_MASK, GTYE4_COM_QPLL0_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_init_cfg1, GTYE4_COM_QPLL0_INIT_CFG1_ADDR, GTYE4_COM_QPLL0_INIT_CFG1_MASK, GTYE4_COM_QPLL0_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_fbdiv, GTYE4_COM_QPLL0_FBDIV_ADDR, GTYE4_COM_QPLL0_FBDIV_MASK, GTYE4_COM_QPLL0_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cfg3, GTYE4_COM_QPLL0_CFG3_ADDR, GTYE4_COM_QPLL0_CFG3_MASK, GTYE4_COM_QPLL0_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cp, GTYE4_COM_QPLL0_CP_ADDR, GTYE4_COM_QPLL0_CP_MASK, GTYE4_COM_QPLL0_CP_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_refclk_div, GTYE4_COM_QPLL0_REFCLK_DIV_ADDR, GTYE4_COM_QPLL0_REFCLK_DIV_MASK, GTYE4_COM_QPLL0_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_ips_refclk_sel, GTYE4_COM_QPLL0_IPS_REFCLK_SEL_ADDR, GTYE4_COM_QPLL0_IPS_REFCLK_SEL_MASK, GTYE4_COM_QPLL0_IPS_REFCLK_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_ips_en, GTYE4_COM_QPLL0_IPS_EN_ADDR, GTYE4_COM_QPLL0_IPS_EN_MASK, GTYE4_COM_QPLL0_IPS_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_lpf, GTYE4_COM_QPLL0_LPF_ADDR, GTYE4_COM_QPLL0_LPF_MASK, GTYE4_COM_QPLL0_LPF_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cfg1_g3, GTYE4_COM_QPLL0_CFG1_G3_ADDR, GTYE4_COM_QPLL0_CFG1_G3_MASK, GTYE4_COM_QPLL0_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cfg2_g3, GTYE4_COM_QPLL0_CFG2_G3_ADDR, GTYE4_COM_QPLL0_CFG2_G3_MASK, GTYE4_COM_QPLL0_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_lpf_g3, GTYE4_COM_QPLL0_LPF_G3_ADDR, GTYE4_COM_QPLL0_LPF_G3_MASK, GTYE4_COM_QPLL0_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_lock_cfg_g3, GTYE4_COM_QPLL0_LOCK_CFG_G3_ADDR, GTYE4_COM_QPLL0_LOCK_CFG_G3_MASK, GTYE4_COM_QPLL0_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, rsvd_attr0, GTYE4_COM_RSVD_ATTR0_ADDR, GTYE4_COM_RSVD_ATTR0_MASK, GTYE4_COM_RSVD_ATTR0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_fbdiv_g3, GTYE4_COM_QPLL0_FBDIV_G3_ADDR, GTYE4_COM_QPLL0_FBDIV_G3_MASK, GTYE4_COM_QPLL0_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_rate_sw_use_drp, GTYE4_COM_QPLL0_RATE_SW_USE_DRP_ADDR, GTYE4_COM_QPLL0_RATE_SW_USE_DRP_MASK, GTYE4_COM_QPLL0_RATE_SW_USE_DRP_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_pcie_en, GTYE4_COM_QPLL0_PCIE_EN_ADDR, GTYE4_COM_QPLL0_PCIE_EN_MASK, GTYE4_COM_QPLL0_PCIE_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye4, rxrecclkout0_sel, GTYE4_COM_RXRECCLKOUT0_SEL_ADDR, GTYE4_COM_RXRECCLKOUT0_SEL_MASK, GTYE4_COM_RXRECCLKOUT0_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_sdm_cfg0, GTYE4_COM_QPLL0_SDM_CFG0_ADDR, GTYE4_COM_QPLL0_SDM_CFG0_MASK, GTYE4_COM_QPLL0_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_sdm_cfg1, GTYE4_COM_QPLL0_SDM_CFG1_ADDR, GTYE4_COM_QPLL0_SDM_CFG1_MASK, GTYE4_COM_QPLL0_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, sdm0initseed0_0, GTYE4_COM_SDM0INITSEED0_0_ADDR, GTYE4_COM_SDM0INITSEED0_0_MASK, GTYE4_COM_SDM0INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, sdm0initseed0_1, GTYE4_COM_SDM0INITSEED0_1_ADDR, GTYE4_COM_SDM0INITSEED0_1_MASK, GTYE4_COM_SDM0INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_sdm_cfg2, GTYE4_COM_QPLL0_SDM_CFG2_ADDR, GTYE4_COM_QPLL0_SDM_CFG2_MASK, GTYE4_COM_QPLL0_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cp_g3, GTYE4_COM_QPLL0_CP_G3_ADDR, GTYE4_COM_QPLL0_CP_G3_MASK, GTYE4_COM_QPLL0_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, rsvd_attr1, GTYE4_COM_RSVD_ATTR1_ADDR, GTYE4_COM_RSVD_ATTR1_MASK, GTYE4_COM_RSVD_ATTR1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll0_cfg4, GTYE4_COM_QPLL0_CFG4_ADDR, GTYE4_COM_QPLL0_CFG4_MASK, GTYE4_COM_QPLL0_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ub_cfg0, GTYE4_COM_UB_CFG0_ADDR, GTYE4_COM_UB_CFG0_MASK, GTYE4_COM_UB_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ub_cfg1, GTYE4_COM_UB_CFG1_ADDR, GTYE4_COM_UB_CFG1_MASK, GTYE4_COM_UB_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ub_cfg2, GTYE4_COM_UB_CFG2_ADDR, GTYE4_COM_UB_CFG2_MASK, GTYE4_COM_UB_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ub_cfg3, GTYE4_COM_UB_CFG3_ADDR, GTYE4_COM_UB_CFG3_MASK, GTYE4_COM_UB_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ub_cfg4, GTYE4_COM_UB_CFG4_ADDR, GTYE4_COM_UB_CFG4_MASK, GTYE4_COM_UB_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ub_cfg5, GTYE4_COM_UB_CFG5_ADDR, GTYE4_COM_UB_CFG5_MASK, GTYE4_COM_UB_CFG5_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ub_cfg6, GTYE4_COM_UB_CFG6_ADDR, GTYE4_COM_UB_CFG6_MASK, GTYE4_COM_UB_CFG6_LSB); +def_gt_pll_masked_reg_rw16(gtye4, bias_cfg0, GTYE4_COM_BIAS_CFG0_ADDR, GTYE4_COM_BIAS_CFG0_MASK, GTYE4_COM_BIAS_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, bias_cfg1, GTYE4_COM_BIAS_CFG1_ADDR, GTYE4_COM_BIAS_CFG1_MASK, GTYE4_COM_BIAS_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, bias_cfg2, GTYE4_COM_BIAS_CFG2_ADDR, GTYE4_COM_BIAS_CFG2_MASK, GTYE4_COM_BIAS_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye4, bias_cfg3, GTYE4_COM_BIAS_CFG3_ADDR, GTYE4_COM_BIAS_CFG3_MASK, GTYE4_COM_BIAS_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, bias_cfg4, GTYE4_COM_BIAS_CFG4_ADDR, GTYE4_COM_BIAS_CFG4_MASK, GTYE4_COM_BIAS_CFG4_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cfg0, GTYE4_COM_QPLL1_CFG0_ADDR, GTYE4_COM_QPLL1_CFG0_MASK, GTYE4_COM_QPLL1_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, common_cfg1, GTYE4_COM_COMMON_CFG1_ADDR, GTYE4_COM_COMMON_CFG1_MASK, GTYE4_COM_COMMON_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, por_cfg, GTYE4_COM_POR_CFG_ADDR, GTYE4_COM_POR_CFG_MASK, GTYE4_COM_POR_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye4, ppf1_cfg, GTYE4_COM_PPF1_CFG_ADDR, GTYE4_COM_PPF1_CFG_MASK, GTYE4_COM_PPF1_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1clkout_rate, GTYE4_COM_QPLL1CLKOUT_RATE_ADDR, GTYE4_COM_QPLL1CLKOUT_RATE_MASK, GTYE4_COM_QPLL1CLKOUT_RATE_LSB); +def_gt_pll_masked_reg_rw16(gtye4, bias_cfg_rsvd, GTYE4_COM_BIAS_CFG_RSVD_ADDR, GTYE4_COM_BIAS_CFG_RSVD_MASK, GTYE4_COM_BIAS_CFG_RSVD_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cfg1, GTYE4_COM_QPLL1_CFG1_ADDR, GTYE4_COM_QPLL1_CFG1_MASK, GTYE4_COM_QPLL1_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cfg2, GTYE4_COM_QPLL1_CFG2_ADDR, GTYE4_COM_QPLL1_CFG2_MASK, GTYE4_COM_QPLL1_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_lock_cfg, GTYE4_COM_QPLL1_LOCK_CFG_ADDR, GTYE4_COM_QPLL1_LOCK_CFG_MASK, GTYE4_COM_QPLL1_LOCK_CFG_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_init_cfg0, GTYE4_COM_QPLL1_INIT_CFG0_ADDR, GTYE4_COM_QPLL1_INIT_CFG0_MASK, GTYE4_COM_QPLL1_INIT_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_init_cfg1, GTYE4_COM_QPLL1_INIT_CFG1_ADDR, GTYE4_COM_QPLL1_INIT_CFG1_MASK, GTYE4_COM_QPLL1_INIT_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_fbdiv, GTYE4_COM_QPLL1_FBDIV_ADDR, GTYE4_COM_QPLL1_FBDIV_MASK, GTYE4_COM_QPLL1_FBDIV_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cfg3, GTYE4_COM_QPLL1_CFG3_ADDR, GTYE4_COM_QPLL1_CFG3_MASK, GTYE4_COM_QPLL1_CFG3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cp, GTYE4_COM_QPLL1_CP_ADDR, GTYE4_COM_QPLL1_CP_MASK, GTYE4_COM_QPLL1_CP_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_refclk_div, GTYE4_COM_QPLL1_REFCLK_DIV_ADDR, GTYE4_COM_QPLL1_REFCLK_DIV_MASK, GTYE4_COM_QPLL1_REFCLK_DIV_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_ips_refclk_sel, GTYE4_COM_QPLL1_IPS_REFCLK_SEL_ADDR, GTYE4_COM_QPLL1_IPS_REFCLK_SEL_MASK, GTYE4_COM_QPLL1_IPS_REFCLK_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye4, sarc_en, GTYE4_COM_SARC_EN_ADDR, GTYE4_COM_SARC_EN_MASK, GTYE4_COM_SARC_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_ips_en, GTYE4_COM_QPLL1_IPS_EN_ADDR, GTYE4_COM_QPLL1_IPS_EN_MASK, GTYE4_COM_QPLL1_IPS_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye4, sarc_sel, GTYE4_COM_SARC_SEL_ADDR, GTYE4_COM_SARC_SEL_MASK, GTYE4_COM_SARC_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_lpf, GTYE4_COM_QPLL1_LPF_ADDR, GTYE4_COM_QPLL1_LPF_MASK, GTYE4_COM_QPLL1_LPF_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cfg1_g3, GTYE4_COM_QPLL1_CFG1_G3_ADDR, GTYE4_COM_QPLL1_CFG1_G3_MASK, GTYE4_COM_QPLL1_CFG1_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cfg2_g3, GTYE4_COM_QPLL1_CFG2_G3_ADDR, GTYE4_COM_QPLL1_CFG2_G3_MASK, GTYE4_COM_QPLL1_CFG2_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_lpf_g3, GTYE4_COM_QPLL1_LPF_G3_ADDR, GTYE4_COM_QPLL1_LPF_G3_MASK, GTYE4_COM_QPLL1_LPF_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_lock_cfg_g3, GTYE4_COM_QPLL1_LOCK_CFG_G3_ADDR, GTYE4_COM_QPLL1_LOCK_CFG_G3_MASK, GTYE4_COM_QPLL1_LOCK_CFG_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, rsvd_attr2, GTYE4_COM_RSVD_ATTR2_ADDR, GTYE4_COM_RSVD_ATTR2_MASK, GTYE4_COM_RSVD_ATTR2_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_fbdiv_g3, GTYE4_COM_QPLL1_FBDIV_G3_ADDR, GTYE4_COM_QPLL1_FBDIV_G3_MASK, GTYE4_COM_QPLL1_FBDIV_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_rate_sw_use_drp, GTYE4_COM_QPLL1_RATE_SW_USE_DRP_ADDR, GTYE4_COM_QPLL1_RATE_SW_USE_DRP_MASK, GTYE4_COM_QPLL1_RATE_SW_USE_DRP_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_pci_en, GTYE4_COM_QPLL1_PCI_EN_ADDR, GTYE4_COM_QPLL1_PCI_EN_MASK, GTYE4_COM_QPLL1_PCI_EN_LSB); +def_gt_pll_masked_reg_rw16(gtye4, rxrecclkout1_sel, GTYE4_COM_RXRECCLKOUT1_SEL_ADDR, GTYE4_COM_RXRECCLKOUT1_SEL_MASK, GTYE4_COM_RXRECCLKOUT1_SEL_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_sdm_cfg0, GTYE4_COM_QPLL1_SDM_CFG0_ADDR, GTYE4_COM_QPLL1_SDM_CFG0_MASK, GTYE4_COM_QPLL1_SDM_CFG0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_sdm_cfg1, GTYE4_COM_QPLL1_SDM_CFG1_ADDR, GTYE4_COM_QPLL1_SDM_CFG1_MASK, GTYE4_COM_QPLL1_SDM_CFG1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, sdm1initseed0_0, GTYE4_COM_SDM1INITSEED0_0_ADDR, GTYE4_COM_SDM1INITSEED0_0_MASK, GTYE4_COM_SDM1INITSEED0_0_LSB); +def_gt_pll_masked_reg_rw16(gtye4, sdm1initseed0_1, GTYE4_COM_SDM1INITSEED0_1_ADDR, GTYE4_COM_SDM1INITSEED0_1_MASK, GTYE4_COM_SDM1INITSEED0_1_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_sdm_cfg2, GTYE4_COM_QPLL1_SDM_CFG2_ADDR, GTYE4_COM_QPLL1_SDM_CFG2_MASK, GTYE4_COM_QPLL1_SDM_CFG2_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cp_g3, GTYE4_COM_QPLL1_CP_G3_ADDR, GTYE4_COM_QPLL1_CP_G3_MASK, GTYE4_COM_QPLL1_CP_G3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, rsvd_attr3, GTYE4_COM_RSVD_ATTR3_ADDR, GTYE4_COM_RSVD_ATTR3_MASK, GTYE4_COM_RSVD_ATTR3_LSB); +def_gt_pll_masked_reg_rw16(gtye4, qpll1_cfg4, GTYE4_COM_QPLL1_CFG4_ADDR, GTYE4_COM_QPLL1_CFG4_MASK, GTYE4_COM_QPLL1_CFG4_LSB); + +// RX +def_gt_ch_masked_reg_rw16(gtye4, rx_data_width_raw, GTYE4_CH_RX_DATA_WIDTH_ADDR, GTYE4_CH_RX_DATA_WIDTH_MASK, GTYE4_CH_RX_DATA_WIDTH_LSB); +int gtye4_ch_get_rx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gtye4, rx_int_data_width_raw, GTYE4_CH_RX_INT_DATAWIDTH_ADDR, GTYE4_CH_RX_INT_DATAWIDTH_MASK, GTYE4_CH_RX_INT_DATAWIDTH_LSB); +int gtye4_ch_get_rx_int_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gtye4, es_prescale, GTYE4_CH_ES_PRESCALE_ADDR, GTYE4_CH_ES_PRESCALE_MASK, GTYE4_CH_ES_PRESCALE_LSB); +def_gt_ch_masked_reg_rw16(gtye4, es_eye_scan_en, GTYE4_CH_ES_EYE_SCAN_EN_ADDR, GTYE4_CH_ES_EYE_SCAN_EN_MASK, GTYE4_CH_ES_EYE_SCAN_EN_LSB); +def_gt_ch_masked_reg_rw16(gtye4, es_errdet_en, GTYE4_CH_ES_ERRDET_EN_ADDR, GTYE4_CH_ES_ERRDET_EN_MASK, GTYE4_CH_ES_ERRDET_EN_LSB); +def_gt_ch_masked_reg_rw16(gtye4, es_control, GTYE4_CH_ES_CONTROL_ADDR, GTYE4_CH_ES_CONTROL_MASK, GTYE4_CH_ES_CONTROL_LSB); + +int gtye4_ch_set_es_qual_mask(struct gt_ch *ch, uint8_t *mask); +int gtye4_ch_set_es_qual_mask_clear(struct gt_ch *ch); + +int gtye4_ch_set_es_sdata_mask(struct gt_ch *ch, uint8_t *mask); +int gtye4_ch_set_es_sdata_mask_width(struct gt_ch *ch, int width); + +def_gt_ch_masked_reg_rw16(gtye4, es_horz_offset, GTYE4_CH_ES_HORZ_OFFSET_ADDR, GTYE4_CH_ES_HORZ_OFFSET_MASK, GTYE4_CH_ES_HORZ_OFFSET_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_eyescan_vs_range, GTYE4_CH_RX_EYESCAN_VS_RANGE_ADDR, GTYE4_CH_RX_EYESCAN_VS_RANGE_MASK, GTYE4_CH_RX_EYESCAN_VS_RANGE_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_eyescan_vs_code, GTYE4_CH_RX_EYESCAN_VS_CODE_ADDR, GTYE4_CH_RX_EYESCAN_VS_CODE_MASK, GTYE4_CH_RX_EYESCAN_VS_CODE_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_eyescan_vs_ut_sign, GTYE4_CH_RX_EYESCAN_VS_UT_SIGN_ADDR, GTYE4_CH_RX_EYESCAN_VS_UT_SIGN_MASK, GTYE4_CH_RX_EYESCAN_VS_UT_SIGN_LSB); +def_gt_ch_masked_reg_rw16(gtye4, rx_eyescan_vs_neg_dir, GTYE4_CH_RX_EYESCAN_VS_NEG_DIR_ADDR, GTYE4_CH_RX_EYESCAN_VS_NEG_DIR_MASK, GTYE4_CH_RX_EYESCAN_VS_NEG_DIR_LSB); +def_gt_ch_masked_reg_read16(gtye4, es_error_count, GTYE4_CH_ES_ERROR_COUNT_ADDR, GTYE4_CH_ES_ERROR_COUNT_MASK, GTYE4_CH_ES_ERROR_COUNT_LSB); +def_gt_ch_masked_reg_read16(gtye4, es_sample_count, GTYE4_CH_ES_SAMPLE_COUNT_ADDR, GTYE4_CH_ES_SAMPLE_COUNT_MASK, GTYE4_CH_ES_SAMPLE_COUNT_LSB); +def_gt_ch_masked_reg_read16(gtye4, es_control_status, GTYE4_CH_ES_CONTROL_STATUS_ADDR, GTYE4_CH_ES_CONTROL_STATUS_MASK, GTYE4_CH_ES_CONTROL_STATUS_LSB); + +int gtye4_ch_get_rx_prbs_error_count(struct gt_ch *ch, uint32_t *val); + +// TX +def_gt_ch_masked_reg_rw16(gtye4, tx_data_width_raw, GTYE4_CH_TX_DATA_WIDTH_ADDR, GTYE4_CH_TX_DATA_WIDTH_MASK, GTYE4_CH_TX_DATA_WIDTH_LSB); +int gtye4_ch_get_tx_data_width(struct gt_ch *ch, uint32_t *val); + +def_gt_ch_masked_reg_rw16(gtye4, tx_int_data_width_raw, GTYE4_CH_TX_INT_DATAWIDTH_ADDR, GTYE4_CH_TX_INT_DATAWIDTH_MASK, GTYE4_CH_TX_INT_DATAWIDTH_LSB); +int gtye4_ch_get_tx_int_data_width(struct gt_ch *ch, uint32_t *val); + +extern const struct gt_quad_ops gtye4_gt_quad_ops; + +#endif /* XCVR_GTYE4_H */