Author: wma
Date: Tue Sep 20 08:56:24 2016
New Revision: 306016
URL: https://svnweb.freebsd.org/changeset/base/306016

Log:
  Update Annapurna Alpine HAL
  
  alpine-hal SerDes file was omitted in the previous commit.
  Files added here.

Added:
  vendor-sys/alpine-hal/dist/al_hal_serdes_hssp.c
     - copied unchanged from r306015, vendor-sys/alpine-hal/dist/al_hal_serdes.c
Deleted:
  vendor-sys/alpine-hal/dist/al_hal_serdes.c

Copied: vendor-sys/alpine-hal/dist/al_hal_serdes_hssp.c (from r306015, 
vendor-sys/alpine-hal/dist/al_hal_serdes.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ vendor-sys/alpine-hal/dist/al_hal_serdes_hssp.c     Tue Sep 20 08:56:24 
2016        (r306016, copy of r306015, 
vendor-sys/alpine-hal/dist/al_hal_serdes.c)
@@ -0,0 +1,3164 @@
+/*******************************************************************************
+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_hssp.h"
+#include "al_hal_serdes_hssp_regs.h"
+#include "al_hal_serdes_hssp_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
+
+#if (!defined(AL_SERDES_BASIC_SERVICES_ONLY)) || 
(AL_SERDES_BASIC_SERVICES_ONLY == 0)
+#define AL_SRDS_ADV_SRVC(func)                 func
+#else
+static void al_serdes_hssp_stub_func(void)
+{
+       al_err("%s: not implemented service called!\n", __func__);
+}
+
+#define AL_SRDS_ADV_SRVC(func)                 ((typeof(func) 
*)al_serdes_hssp_stub_func)
+#endif
+
+/**
+ * SERDES core reg read
+ */
+static inline uint8_t al_serdes_grp_reg_read(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_reg_page         page,
+       enum al_serdes_reg_type         type,
+       uint16_t                        offset);
+
+/**
+ * SERDES core reg write
+ */
+static inline void al_serdes_grp_reg_write(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_reg_page         page,
+       enum al_serdes_reg_type         type,
+       uint16_t                        offset,
+       uint8_t                         data);
+
+/**
+ * SERDES core masked reg write
+ */
+static inline void al_serdes_grp_reg_masked_write(
+       struct al_serdes_grp_obj        *obj,
+       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_grp_obj        *obj,
+       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_grp_obj        *obj);
+
+/**
+ * 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_grp_obj        *obj,
+       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_grp_obj        *obj);
+
+/******************************************************************************/
+/******************************************************************************/
+static enum al_serdes_type al_serdes_hssp_type_get(void)
+{
+       return AL_SRDS_TYPE_HSSP;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static int al_serdes_reg_read(
+       struct al_serdes_grp_obj        *obj,
+       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, %u)\n",
+               __func__,
+               obj,
+               page,
+               type,
+               offset);
+
+       al_assert(obj);
+       al_assert(data);
+       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,
+               page,
+               type,
+               offset);
+
+       al_dbg(
+               "%s: return(%u)\n",
+               __func__,
+               *data);
+
+       return status;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static int al_serdes_reg_write(
+       struct al_serdes_grp_obj        *obj,
+       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, %u, %u)\n",
+               __func__,
+               obj,
+               page,
+               type,
+               offset,
+               data);
+
+       al_assert(obj);
+       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,
+               page,
+               type,
+               offset,
+               data);
+
+       return status;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+#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
+static void al_serdes_bist_overrides_enable(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_rate             rate)
+{
+       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(
+                       obj,
+                       (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(
+                       obj,
+                       (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(
+               obj,
+               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(
+               obj,
+               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(
+               obj,
+               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(
+               obj,
+               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(
+                       obj,
+                       (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(
+                       obj,
+                       (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(
+                       obj,
+                       (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(
+                       obj,
+                       (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);
+       }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_bist_overrides_disable(
+       struct al_serdes_grp_obj        *obj)
+{
+       int i;
+
+       al_serdes_grp_reg_masked_write(
+               obj,
+               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(
+                       obj,
+                       (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(
+                       obj,
+                       (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);
+       }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_rx_rate_change(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_rate             rate)
+{
+       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(
+                                  obj,
+                                  (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);
+       }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_group_pm_set(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_pm               pm)
+{
+       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(obj);
+
+       al_serdes_grp_reg_masked_write(
+               obj,
+               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(obj);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_lane_rx_rate_change_sw_flow_en(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane     lane)
+{
+       al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, 
AL_SRDS_REG_TYPE_PMA, 201, 0xfc);
+       al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, 
AL_SRDS_REG_TYPE_PMA, 202, 0xff);
+       al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, 
AL_SRDS_REG_TYPE_PMA, 203, 0xff);
+       al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, 
AL_SRDS_REG_TYPE_PMA, 204, 0xff);
+       al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, 
AL_SRDS_REG_TYPE_PMA, 205, 0x7f);
+       al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, 
AL_SRDS_REG_TYPE_PMA, 205, 0xff);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_lane_rx_rate_change_sw_flow_dis(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane)
+{
+       al_serdes_reg_write(obj, (enum al_serdes_reg_page)lane, 
AL_SRDS_REG_TYPE_PMA, 205, 0x7f);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_lane_pcie_rate_override_enable_set(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       al_bool                         en)
+{
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (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);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static al_bool al_serdes_lane_pcie_rate_override_is_enabled(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane)
+{
+       return (al_serdes_grp_reg_read(
+               obj,
+               (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) ? AL_TRUE : AL_FALSE;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane)
+{
+       return (al_serdes_grp_reg_read(
+               obj,
+               (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;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_lane_pcie_rate_set(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       enum al_serdes_pcie_rate        rate)
+{
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (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);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_lane_pm_set(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       enum al_serdes_pm               rx_pm,
+       enum al_serdes_pm               tx_pm)
+{
+       uint8_t rx_pm_val;
+       uint8_t tx_pm_val;
+
+       switch (rx_pm) {
+       case AL_SRDS_PM_PD:
+               rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD;
+               break;
+       case AL_SRDS_PM_P2:
+               rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2;
+               break;
+       case AL_SRDS_PM_P1:
+               rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1;
+               break;
+       case AL_SRDS_PM_P0S:
+               rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S;
+               break;
+       case AL_SRDS_PM_P0:
+               rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0;
+               break;
+       default:
+               al_err("%s: invalid rx power mode (%d)\n",  __func__, rx_pm);
+               al_assert(0);
+               rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0;
+       }
+
+       switch (tx_pm) {
+       case AL_SRDS_PM_PD:
+               tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD;
+               break;
+       case AL_SRDS_PM_P2:
+               tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2;
+               break;
+       case AL_SRDS_PM_P1:
+               tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1;
+               break;
+       case AL_SRDS_PM_P0S:
+               tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S;
+               break;
+       case AL_SRDS_PM_P0:
+               tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0;
+               break;
+       default:
+               al_err("%s: invalid tx power mode (%d)\n",  __func__, tx_pm);
+               al_assert(0);
+               tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0;
+       }
+
+       if (rx_pm == AL_SRDS_PM_PD)
+               _al_serdes_lane_rx_rate_change_sw_flow_dis(obj, lane);
+
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM,
+               SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK,
+               rx_pm_val);
+
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM,
+               SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK,
+               tx_pm_val);
+
+       if (rx_pm != AL_SRDS_PM_PD)
+               _al_serdes_lane_rx_rate_change_sw_flow_en_cond(obj, lane);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_pma_hard_reset_group(
+       struct al_serdes_grp_obj        *obj,
+       al_bool                         enable)
+{
+       if (enable)
+               al_serdes_group_rx_rate_change_sw_flow_dis(obj);
+
+       /* Enable Hard Reset Override */
+       al_serdes_grp_reg_masked_write(
+               obj,
+               AL_SRDS_REG_PAGE_4_COMMON,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS);
+
+       /* Assert/Deassert Hard Reset Override */
+       al_serdes_grp_reg_masked_write(
+               obj,
+               AL_SRDS_REG_PAGE_4_COMMON,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK,
+               enable ?
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT :
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT);
+
+       if (!enable)
+               al_serdes_group_rx_rate_change_sw_flow_en_cond(obj);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_pma_hard_reset_lane(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       al_bool                         enable)
+{
+       if (enable)
+               _al_serdes_lane_rx_rate_change_sw_flow_dis(obj, lane);
+
+       /* Enable Hard Reset Override */
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS);
+
+       /* Assert/Deassert Hard Reset Override */
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM,
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK,
+               enable ?
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT :
+               SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT);
+
+       if (!enable)
+               _al_serdes_lane_rx_rate_change_sw_flow_en_cond(obj, lane);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+#if    (SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM !=\
+       SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM) ||\
+       (SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM !=\
+       SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM) ||\
+       (SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM !=\
+        SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM) ||\
+       (SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM !=\
+        SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM)
+#error Wrong assumption
+#endif
+
+static void al_serdes_loopback_control(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       enum al_serdes_lb_mode          mode)
+{
+       uint8_t val = 0;
+
+       switch (mode) {
+       case AL_SRDS_LB_MODE_OFF:
+               break;
+       case AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX:
+               val = SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN;
+               break;
+       case AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX:
+               val = SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN;
+               break;
+       case AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO:
+               val = SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN;
+               break;
+       case AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX:
+               val = SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN |
+                       SERDES_IREG_FLD_LB_CDRCLK2TXEN;
+               break;
+       default:
+               al_err("%s: invalid mode (%d)\n",  __func__, mode);
+               al_assert(0);
+       }
+
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM,
+               SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN |
+               SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN |
+               SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN |
+               SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN |
+               SERDES_IREG_FLD_LB_CDRCLK2TXEN,
+               val);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_bist_pattern_select(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_bist_pattern     pattern,
+       uint8_t                         *user_data)
+{
+       uint8_t val = 0;
+
+       switch (pattern) {
+       case AL_SRDS_BIST_PATTERN_USER:
+               al_assert(user_data);
+               val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER;
+               break;
+       case AL_SRDS_BIST_PATTERN_PRBS7:
+               val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7;
+               break;
+       case AL_SRDS_BIST_PATTERN_PRBS23:
+               val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23;
+               break;
+       case AL_SRDS_BIST_PATTERN_PRBS31:
+               val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31;
+               break;
+       case AL_SRDS_BIST_PATTERN_CLK1010:
+               val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010;
+               break;
+       default:
+               al_err("%s: invalid pattern (%d)\n", __func__, pattern);
+               al_assert(0);
+       }
+
+       if (pattern == AL_SRDS_BIST_PATTERN_USER) {
+               int i;
+
+               for (i = 0; i < SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES; i++)
+                       al_serdes_grp_reg_write(
+                               obj,
+                               AL_SRDS_REG_PAGE_4_COMMON,
+                               AL_SRDS_REG_TYPE_PMA,
+                               SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(i),
+                               user_data[i]);
+       }
+
+       al_serdes_grp_reg_masked_write(
+               obj,
+               AL_SRDS_REG_PAGE_4_COMMON,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM,
+               SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK,
+               val);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_bist_tx_enable(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       al_bool                         enable)
+{
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM,
+               SERDES_IREG_FLD_PCSTXBIST_EN,
+               enable ? SERDES_IREG_FLD_PCSTXBIST_EN : 0);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_bist_tx_err_inject(
+       struct al_serdes_grp_obj        *obj)
+{
+       al_serdes_grp_reg_masked_write(
+               obj,
+               AL_SRDS_REG_PAGE_4_COMMON,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM,
+               SERDES_IREG_FLD_TXBIST_BITERROR_EN,
+               SERDES_IREG_FLD_TXBIST_BITERROR_EN);
+
+       al_serdes_grp_reg_masked_write(
+               obj,
+               AL_SRDS_REG_PAGE_4_COMMON,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM,
+               SERDES_IREG_FLD_TXBIST_BITERROR_EN,
+               0);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static void al_serdes_bist_rx_enable(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       al_bool                         enable)
+{
+       al_serdes_grp_reg_masked_write(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM,
+               SERDES_IREG_FLD_PCSRXBIST_EN,
+               enable ? SERDES_IREG_FLD_PCSRXBIST_EN : 0);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+#if    (SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM !=\
+       SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM)
+#error Wrong assumption
+#endif
+
+static void al_serdes_bist_rx_status(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_lane             lane,
+       al_bool                         *is_locked,
+       al_bool                         *err_cnt_overflow,
+       uint32_t                        *err_cnt)
+{
+       uint8_t status_reg_val;
+       uint16_t err_cnt_msb_reg_val;
+       uint16_t err_cnt_lsb_reg_val;
+
+       status_reg_val = al_serdes_grp_reg_read(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM);
+
+       err_cnt_msb_reg_val = al_serdes_grp_reg_read(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM);
+
+       err_cnt_lsb_reg_val = al_serdes_grp_reg_read(
+               obj,
+               (enum al_serdes_reg_page)lane,
+               AL_SRDS_REG_TYPE_PMA,
+               SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM);
+
+       *is_locked =
+               (status_reg_val & SERDES_IREG_FLD_RXBIST_RXLOCKED) ?
+               AL_TRUE : AL_FALSE;
+
+       *err_cnt_overflow =
+               (status_reg_val & SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW) ?
+               AL_TRUE : AL_FALSE;
+
+       *err_cnt = (err_cnt_msb_reg_val << 8) + err_cnt_lsb_reg_val;
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static inline uint8_t al_serdes_grp_reg_read(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_reg_page         page,
+       enum al_serdes_reg_type         type,
+       uint16_t                        offset)
+{
+       struct al_serdes_regs __iomem   *regs_base = obj->regs_base;
+
+       al_reg_write32(
+               &regs_base->gen.reg_addr,
+               SRDS_CORE_REG_ADDR(page, type, offset));
+
+       return al_reg_read32(&regs_base->gen.reg_data);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static inline void al_serdes_grp_reg_write(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_reg_page         page,
+       enum al_serdes_reg_type         type,
+       uint16_t                        offset,
+       uint8_t                         data)
+{
+       struct al_serdes_regs __iomem   *regs_base = obj->regs_base;
+
+       al_reg_write32(
+               &regs_base->gen.reg_addr,
+               SRDS_CORE_REG_ADDR(page, type, offset));
+
+       al_reg_write32(&regs_base->gen.reg_data, data);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static inline void al_serdes_ns_delay(int cnt)
+{
+       al_udelay((cnt + 999) / 1000);
+}
+
+/******************************************************************************/
+/******************************************************************************/
+static inline void al_serdes_grp_reg_masked_write(
+       struct al_serdes_grp_obj        *obj,
+       enum al_serdes_reg_page         page,
+       enum al_serdes_reg_type         type,
+       uint16_t                        offset,
+       uint8_t                         mask,
+       uint8_t                         data)
+{
+       uint8_t val;
+       enum al_serdes_reg_page start_page = page;
+       enum al_serdes_reg_page end_page   = page;
+       enum al_serdes_reg_page iter_page;
+
+       if (page == AL_SRDS_REG_PAGE_0123_LANES_0123) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to