// SPDX-License-Identifier: BSD-2-Clause-Views /* * Copyright (c) 2022-2023 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); }