svn commit: r294828 - in vendor-sys/alpine-hal/2.7: . eth
Zbigniew Bodek
zbb at FreeBSD.org
Tue Jan 26 14:30:05 UTC 2016
Author: zbb
Date: Tue Jan 26 14:30:03 2016
New Revision: 294828
URL: https://svnweb.freebsd.org/changeset/base/294828
Log:
Add networking components to Annapurna Labs HAL for Alpine PoC
Added files required by the NIC driver.
HAL version: 2.7
Obtained from: Semihalf
Sponsored by: Annapurna Labs
Added:
vendor-sys/alpine-hal/2.7/al_hal_iofic.c (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_serdes.c (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_serdes.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_serdes_internal_regs.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_serdes_regs.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_config.c (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_config.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_debug.c (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_debug.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_iofic.c (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_iofic.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_iofic_regs.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_main.c (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_regs.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_regs_gen.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_regs_m2s.h (contents, props changed)
vendor-sys/alpine-hal/2.7/al_hal_udma_regs_s2m.h (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/
vendor-sys/alpine-hal/2.7/eth/al_hal_an_lt_wrapper_regs.h (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/al_hal_eth.h (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/al_hal_eth_alu.h (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/al_hal_eth_ec_regs.h (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/al_hal_eth_kr.c (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/al_hal_eth_kr.h (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/al_hal_eth_mac_regs.h (contents, props changed)
vendor-sys/alpine-hal/2.7/eth/al_hal_eth_main.c (contents, props changed)
Added: vendor-sys/alpine-hal/2.7/al_hal_iofic.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor-sys/alpine-hal/2.7/al_hal_iofic.c Tue Jan 26 14:30:03 2016 (r294828)
@@ -0,0 +1,291 @@
+/*-
+*******************************************************************************
+Copyright (C) 2015 Annapurna Labs Ltd.
+
+This file may be licensed under the terms of the Annapurna Labs Commercial
+License Agreement.
+
+Alternatively, this file can be distributed under the terms of the GNU General
+Public License V2 as published by the Free Software Foundation and can be
+found at http://www.gnu.org/licenses/gpl-2.0.html
+
+Alternatively, redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+ * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
+
+*******************************************************************************/
+
+/**
+ * @{
+ * @file al_hal_iofic.c
+ *
+ * @brief interrupt controller hal
+ *
+ */
+
+#include "al_hal_iofic.h"
+#include "al_hal_iofic_regs.h"
+
+/*
+ * configure the interrupt registers, interrupts will are kept masked
+ */
+int al_iofic_config(void __iomem *regs_base, int group, uint32_t flags)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ al_reg_write32(®s->ctrl[group].int_control_grp, flags);
+
+ return 0;
+}
+
+/*
+ * configure the moderation timer resolution for a given group
+ */
+int al_iofic_moder_res_config(void __iomem *regs_base, int group,
+ uint8_t resolution)
+
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+ uint32_t reg;
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ reg = al_reg_read32(®s->ctrl[group].int_control_grp);
+ AL_REG_FIELD_SET(reg,
+ INT_CONTROL_GRP_MOD_RES_MASK,
+ INT_CONTROL_GRP_MOD_RES_SHIFT,
+ resolution);
+ al_reg_write32(®s->ctrl[group].int_control_grp, reg);
+
+ return 0;
+}
+
+/*
+ * configure the moderation timer interval for a given legacy interrupt group
+ */
+int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group,
+ uint8_t interval)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+ uint32_t reg;
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ reg = al_reg_read32(®s->ctrl[group].int_control_grp);
+ AL_REG_FIELD_SET(reg,
+ INT_CONTROL_GRP_MOD_INTV_MASK,
+ INT_CONTROL_GRP_MOD_INTV_SHIFT,
+ interval);
+ al_reg_write32(®s->ctrl[group].int_control_grp, reg);
+
+ return 0;
+}
+
+
+/*
+ * configure the moderation timer interval for a given msix vector.
+ */
+int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group,
+ uint8_t vector, uint8_t interval)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+ uint32_t reg;
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ reg = al_reg_read32(®s->grp_int_mod[group][vector].grp_int_mod_reg);
+ AL_REG_FIELD_SET(reg,
+ INT_MOD_INTV_MASK,
+ INT_MOD_INTV_SHIFT,
+ interval);
+ al_reg_write32(®s->grp_int_mod[group][vector].grp_int_mod_reg, reg);
+
+ return 0;
+}
+
+/*
+ * configure the vmid attributes for a given msix vector.
+ */
+int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group,
+ uint8_t vector, uint32_t vmid, uint8_t vmid_en)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+ uint32_t reg = 0;
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ AL_REG_FIELD_SET(reg,
+ INT_MSIX_VMID_MASK,
+ INT_MSIX_VMID_SHIFT,
+ vmid);
+ AL_REG_BIT_VAL_SET(reg,
+ INT_MSIX_VMID_EN_SHIFT,
+ vmid_en);
+
+ al_reg_write32(®s->grp_int_mod[group][vector].grp_int_vmid_reg, reg);
+
+ return 0;
+}
+
+/*
+ * return the offset of the unmask register for a given group
+ */
+uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ return ®s->ctrl[group].int_mask_clear_grp;
+}
+
+
+/*
+ * unmask specific interrupts for a given group
+ */
+void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ /*
+ * use the mask clear register, no need to read the mask register
+ * itself. write 0 to unmask, 1 has no effect
+ */
+ al_reg_write32_relaxed(®s->ctrl[group].int_mask_clear_grp, ~mask);
+}
+
+/*
+ * mask specific interrupts for a given group
+ */
+void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+ uint32_t reg;
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ reg = al_reg_read32(®s->ctrl[group].int_mask_grp);
+
+ al_reg_write32(®s->ctrl[group].int_mask_grp, reg | mask);
+}
+
+/*
+ * read the mask for a given group
+ */
+uint32_t al_iofic_read_mask(void __iomem *regs_base, int group)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ return al_reg_read32(®s->ctrl[group].int_mask_grp);
+}
+
+/*
+ * read interrupt cause register for a given group
+ */
+uint32_t al_iofic_read_cause(void __iomem *regs_base, int group)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ return al_reg_read32(®s->ctrl[group].int_cause_grp);
+}
+
+/*
+ * clear bits in the interrupt cause register for a given group
+ */
+void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ /* inverse mask, writing 1 has no effect */
+ al_reg_write32(®s->ctrl[group].int_cause_grp, ~mask);
+}
+
+/*
+ * Set the cause register for a given group
+ */
+void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ al_reg_write32(®s->ctrl[group].int_cause_set_grp, mask);
+}
+
+
+/*
+ * unmask specific interrupts from aborting the udma a given group
+ */
+void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ al_reg_write32(®s->ctrl[group].int_abort_msk_grp, mask);
+
+}
+
+/*
+ * trigger all interrupts that are waiting for moderation timers to expire
+ */
+void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group)
+{
+ struct al_iofic_regs __iomem *regs = (struct al_iofic_regs __iomem *)(regs_base);
+ uint32_t reg = 0;
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ al_assert(regs_base);
+ al_assert(group < AL_IOFIC_MAX_GROUPS);
+
+ reg = al_reg_read32(®s->ctrl[group].int_control_grp);
+ reg |= INT_CONTROL_GRP_MOD_RST;
+
+ al_reg_write32(®s->ctrl[group].int_control_grp, reg);
+}
+
+/** @} end of interrupt controller group */
Added: vendor-sys/alpine-hal/2.7/al_hal_serdes.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor-sys/alpine-hal/2.7/al_hal_serdes.c Tue Jan 26 14:30:03 2016 (r294828)
@@ -0,0 +1,3228 @@
+/*-
+*******************************************************************************
+Copyright (C) 2015 Annapurna Labs Ltd.
+
+This file may be licensed under the terms of the Annapurna Labs Commercial
+License Agreement.
+
+Alternatively, this file can be distributed under the terms of the GNU General
+Public License V2 as published by the Free Software Foundation and can be
+found at http://www.gnu.org/licenses/gpl-2.0.html
+
+Alternatively, redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+ * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
+
+*******************************************************************************/
+
+#include "al_hal_serdes.h"
+#include "al_hal_serdes_regs.h"
+#include "al_hal_serdes_internal_regs.h"
+
+#define SRDS_CORE_REG_ADDR(page, type, offset)\
+ (((page) << 13) | ((type) << 12) | (offset))
+
+/* Link Training configuration */
+#define AL_SERDES_TX_DEEMPH_SUM_MAX 0x1b
+
+/* c configurations */
+#define AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL 0x1b
+#define AL_SERDES_TX_DEEMPH_C_ZERO_MIN_VAL 0
+#define AL_SERDES_TX_DEEMPH_C_ZERO_PRESET AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL
+
+/* c(+1) configurations */
+#define AL_SERDES_TX_DEEMPH_C_PLUS_MAX_VAL 0x9
+#define AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL 0
+#define AL_SERDES_TX_DEEMPH_C_PLUS_PRESET AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL
+
+/* c(-1) configurations */
+#define AL_SERDES_TX_DEEMPH_C_MINUS_MAX_VAL 0x6
+#define AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL 0
+#define AL_SERDES_TX_DEEMPH_C_MINUS_PRESET AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL
+
+/* Rx equal total delay = MDELAY * TRIES */
+#define AL_SERDES_RX_EQUAL_MDELAY 10
+#define AL_SERDES_RX_EQUAL_TRIES 50
+
+/* Rx eye calculation delay = MDELAY * TRIES */
+#define AL_SERDES_RX_EYE_CAL_MDELAY 50
+#define AL_SERDES_RX_EYE_CAL_TRIES 70
+
+
+/**
+ * Prototypes for _lane_ compatibility
+ */
+int al_serdes_lane_read(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t *data);
+
+int al_serdes_lane_write(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t data);
+
+
+/**
+ * SERDES core reg/lane read
+ */
+static inline uint8_t al_serdes_grp_reg_read(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_reg_page page,
+ enum al_serdes_reg_type type,
+ uint16_t offset);
+
+static inline uint8_t al_serdes_grp_lane_read(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_lane page,
+ enum al_serdes_reg_type type,
+ uint16_t offset);
+
+/**
+ * SERDES core reg/lane write
+ */
+static inline void al_serdes_grp_reg_write(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_reg_page page,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t data);
+
+static inline void al_serdes_grp_lane_write(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_lane lane,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t data);
+
+/**
+ * SERDES core masked reg/lane write
+ */
+static inline void al_serdes_grp_reg_masked_write(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_reg_page page,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t mask,
+ uint8_t data);
+
+/**
+ * Lane Rx rate change software flow disable
+ */
+static void _al_serdes_lane_rx_rate_change_sw_flow_dis(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_lane lane);
+
+/**
+ * Group Rx rate change software flow enable if all conditions met
+ */
+static void al_serdes_group_rx_rate_change_sw_flow_dis(
+ struct al_serdes_group_info *grp_info);
+
+/**
+ * Lane Rx rate change software flow enable if all conditions met
+ */
+static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_lane lane);
+
+/**
+ * Group Rx rate change software flow enable if all conditions met
+ */
+static void al_serdes_group_rx_rate_change_sw_flow_en_cond(
+ struct al_serdes_group_info *grp_info);
+
+
+static inline void al_serdes_grp_lane_masked_write(
+ struct al_serdes_group_info *grp_info,
+ enum al_serdes_lane lane,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t mask,
+ uint8_t data);
+
+/******************************************************************************/
+/******************************************************************************/
+int al_serdes_handle_init(
+ void __iomem *serdes_regs_base,
+ struct al_serdes_obj *obj)
+{
+ int i;
+
+ al_dbg(
+ "%s(%p, %p)\n",
+ __func__,
+ serdes_regs_base,
+ obj);
+
+ al_assert(serdes_regs_base);
+
+ for (i = 0; i < AL_SRDS_NUM_GROUPS; i++) {
+ obj->grp_info[i].pobj = obj;
+
+ obj->grp_info[i].regs_base =
+ &((struct al_serdes_regs *)serdes_regs_base)[i];
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+int al_serdes_reg_read(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_reg_page page,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t *data)
+{
+ int status = 0;
+
+ al_dbg(
+ "%s(%p, %d, %d, %d, %u)\n",
+ __func__,
+ obj,
+ grp,
+ page,
+ type,
+ offset);
+
+ al_assert(obj);
+ al_assert(data);
+ al_assert(((int)grp) >= AL_SRDS_GRP_A);
+ al_assert(((int)grp) <= AL_SRDS_GRP_D);
+ al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0);
+ al_assert(((int)page) <= AL_SRDS_REG_PAGE_4_COMMON);
+ al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA);
+ al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS);
+
+ *data = al_serdes_grp_reg_read(
+ &obj->grp_info[grp],
+ page,
+ type,
+ offset);
+
+ al_dbg(
+ "%s: return(%u)\n",
+ __func__,
+ *data);
+
+ return status;
+}
+
+int al_serdes_lane_read(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t *data)
+{
+ return al_serdes_reg_read(obj, grp, (enum al_serdes_reg_page)lane, type,
+ offset, data);
+}
+/******************************************************************************/
+/******************************************************************************/
+int al_serdes_reg_write(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_reg_page page,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t data)
+{
+ int status = 0;
+
+ al_dbg(
+ "%s(%p, %d, %d, %d, %u, %u)\n",
+ __func__,
+ obj,
+ grp,
+ page,
+ type,
+ offset,
+ data);
+
+ al_assert(obj);
+ al_assert(((int)grp) >= AL_SRDS_GRP_A);
+ al_assert(((int)grp) <= AL_SRDS_GRP_D);
+ al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0);
+ al_assert(((int)page) <= AL_SRDS_REG_PAGE_0123_LANES_0123);
+ al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA);
+ al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS);
+
+ al_serdes_grp_reg_write(
+ &obj->grp_info[grp],
+ page,
+ type,
+ offset,
+ data);
+
+ return status;
+}
+
+int al_serdes_lane_write(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane,
+ enum al_serdes_reg_type type,
+ uint16_t offset,
+ uint8_t data)
+{
+ return al_serdes_reg_write(obj, grp, (enum al_serdes_reg_page)lane,
+ type, offset, data);
+}
+/******************************************************************************/
+/******************************************************************************/
+#if (SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM != SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM != SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_LB_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM)
+#error "Wrong assumption!"
+#endif
+void al_serdes_bist_overrides_enable(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_rate rate)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+ int i;
+
+ uint8_t rx_rate_val;
+ uint8_t tx_rate_val;
+
+ switch (rate) {
+ case AL_SRDS_RATE_1_8:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8;
+ tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8;
+ break;
+ case AL_SRDS_RATE_1_4:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4;
+ tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4;
+ break;
+ case AL_SRDS_RATE_1_2:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2;
+ tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2;
+ break;
+ case AL_SRDS_RATE_FULL:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
+ tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1;
+ break;
+ default:
+ al_err("%s: invalid rate (%d)\n", __func__, rate);
+ al_assert(0);
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
+ tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1;
+ }
+
+ for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM,
+ SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK |
+ SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK,
+ SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 |
+ SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM,
+ SERDES_IREG_FLD_PCSRX_DIVRATE_MASK |
+ SERDES_IREG_FLD_PCSTX_DIVRATE_MASK,
+ rx_rate_val | tx_rate_val);
+ }
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ AL_SRDS_REG_PAGE_4_COMMON,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN |
+ SERDES_IREG_FLD_CMNPCS_LOCWREN |
+ SERDES_IREG_FLD_CMNPCSBIST_LOCWREN |
+ SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN,
+ 0);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ AL_SRDS_REG_PAGE_4_COMMON,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN |
+ SERDES_IREG_FLD_CMNPCS_LOCWREN |
+ SERDES_IREG_FLD_CMNPCSBIST_LOCWREN |
+ SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN,
+ 0);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ AL_SRDS_REG_PAGE_4_COMMON,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_PCS_LOCWREN,
+ 0);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ AL_SRDS_REG_PAGE_4_COMMON,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM,
+ SERDES_IREG_FLD_CMNPCS_TXENABLE,
+ SERDES_IREG_FLD_CMNPCS_TXENABLE);
+
+ for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN |
+ SERDES_IREG_FLD_LB_LOCWREN |
+ SERDES_IREG_FLD_PCSRX_LOCWREN |
+ SERDES_IREG_FLD_PCSRXBIST_LOCWREN |
+ SERDES_IREG_FLD_PCSRXEQ_LOCWREN |
+ SERDES_IREG_FLD_PCSTX_LOCWREN,
+ 0);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_PCSTXBIST_LOCWREN,
+ 0);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM,
+ SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN,
+ 0);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM,
+ SERDES_IREG_FLD_RXLOCK2REF_OVREN,
+ SERDES_IREG_FLD_RXLOCK2REF_OVREN);
+ }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_bist_overrides_disable(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+ int i;
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ AL_SRDS_REG_PAGE_4_COMMON,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_CMNPCSBIST_LOCWREN,
+ SERDES_IREG_FLD_CMNPCSBIST_LOCWREN);
+
+ for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_LB_LOCWREN |
+ SERDES_IREG_FLD_PCSRXBIST_LOCWREN,
+ SERDES_IREG_FLD_LB_LOCWREN |
+ SERDES_IREG_FLD_PCSRXBIST_LOCWREN);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM,
+ SERDES_IREG_FLD_PCSTXBIST_LOCWREN,
+ SERDES_IREG_FLD_PCSTXBIST_LOCWREN);
+ }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_rx_rate_change(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_rate rate)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+ int i;
+
+ uint8_t rx_rate_val;
+
+ switch (rate) {
+ case AL_SRDS_RATE_1_8:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8;
+ break;
+ case AL_SRDS_RATE_1_4:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4;
+ break;
+ case AL_SRDS_RATE_1_2:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2;
+ break;
+ case AL_SRDS_RATE_FULL:
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
+ break;
+ default:
+ al_err("%s: invalid rate (%d)\n", __func__, rate);
+ rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
+ break;
+ }
+
+ for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)i,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM,
+ SERDES_IREG_FLD_PCSRX_DIVRATE_MASK,
+ rx_rate_val);
+ }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_group_pm_set(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_pm pm)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+
+ uint8_t pm_val;
+
+ switch (pm) {
+ case AL_SRDS_PM_PD:
+ pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD;
+ break;
+ case AL_SRDS_PM_P2:
+ pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2;
+ break;
+ case AL_SRDS_PM_P1:
+ pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1;
+ break;
+ case AL_SRDS_PM_P0S:
+ pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S;
+ break;
+ case AL_SRDS_PM_P0:
+ pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0;
+ break;
+ default:
+ al_err("%s: invalid power mode (%d)\n", __func__, pm);
+ al_assert(0);
+ pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0;
+ }
+
+ if (pm == AL_SRDS_PM_PD)
+ al_serdes_group_rx_rate_change_sw_flow_dis(grp_info);
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ AL_SRDS_REG_PAGE_4_COMMON,
+ AL_SRDS_REG_TYPE_PMA,
+ SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM,
+ SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK,
+ pm_val);
+
+ if (pm != AL_SRDS_PM_PD)
+ al_serdes_group_rx_rate_change_sw_flow_en_cond(grp_info);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_lane_rx_rate_change_sw_flow_en(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane)
+{
+ al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 201, 0xfc);
+ al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 202, 0xff);
+ al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 203, 0xff);
+ al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 204, 0xff);
+ al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f);
+ al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0xff);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_lane_rx_rate_change_sw_flow_dis(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane)
+{
+ al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_lane_pcie_rate_override_enable_set(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane,
+ al_bool en)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)lane,
+ AL_SRDS_REG_TYPE_PCS,
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM,
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA,
+ en ? SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA : 0);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+al_bool al_serdes_lane_pcie_rate_override_is_enabled(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+
+ return (al_serdes_grp_lane_read(
+ grp_info,
+ lane,
+ AL_SRDS_REG_TYPE_PCS,
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM) &
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA) ? AL_TRUE : AL_FALSE;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+
+ return (al_serdes_grp_reg_read(
+ grp_info,
+ (enum al_serdes_reg_page)lane,
+ AL_SRDS_REG_TYPE_PCS,
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM) &
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK) >>
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_lane_pcie_rate_set(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane,
+ enum al_serdes_pcie_rate rate)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+
+ al_serdes_grp_reg_masked_write(
+ grp_info,
+ (enum al_serdes_reg_page)lane,
+ AL_SRDS_REG_TYPE_PCS,
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM,
+ SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK,
+ rate << SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+void al_serdes_lane_pm_set(
+ struct al_serdes_obj *obj,
+ enum al_serdes_group grp,
+ enum al_serdes_lane lane,
+ enum al_serdes_pm rx_pm,
+ enum al_serdes_pm tx_pm)
+{
+ struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
+
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-vendor
mailing list