1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00
corundum/utils/xcvr_gt.c
Alex Forencich 448fa8eb4c Use SPDX
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2023-06-26 11:44:57 -07:00

288 lines
6.3 KiB
C

// SPDX-License-Identifier: BSD-2-Clause-Views
/*
* Copyright (c) 2022-2023 The Regents of the University of California
*/
#include <stdlib.h>
#include "drp.h"
#include "xcvr_gt.h"
#include "xcvr_gthe3.h"
#include "xcvr_gtye3.h"
#include "xcvr_gthe4.h"
#include "xcvr_gtye4.h"
#include <stdio.h>
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 = &gthe3_gt_quad_ops;
break;
case 0x0803:
quad->ops = &gtye3_gt_quad_ops;
break;
case 0x0902:
quad->ops = &gthe4_gt_quad_ops;
break;
case 0x0903:
quad->ops = &gtye4_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);
}