The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/alpine-hal/al_hal_serdes_25g.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************************
    2 Copyright (C) 2015 Annapurna Labs Ltd.
    3 
    4 This file may be licensed under the terms of the Annapurna Labs Commercial
    5 License Agreement.
    6 
    7 Alternatively, this file can be distributed under the terms of the GNU General
    8 Public License V2 as published by the Free Software Foundation and can be
    9 found at http://www.gnu.org/licenses/gpl-2.0.html
   10 
   11 Alternatively, redistribution and use in source and binary forms, with or
   12 without modification, are permitted provided that the following conditions are
   13 met:
   14 
   15     *     Redistributions of source code must retain the above copyright notice,
   16 this list of conditions and the following disclaimer.
   17 
   18     *     Redistributions in binary form must reproduce the above copyright
   19 notice, this list of conditions and the following disclaimer in
   20 the documentation and/or other materials provided with the
   21 distribution.
   22 
   23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   24 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   26 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   27 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
   30 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33 
   34 *******************************************************************************/
   35 
   36 #include "al_hal_serdes_25g.h"
   37 #include "al_hal_serdes_25g_regs.h"
   38 #include "al_hal_serdes_25g_internal_regs.h"
   39 
   40 #define AL_SERDES_MB_MAX_DATA_LEN               8
   41 
   42 #define AL_SERDES_25G_WAIT_FOR_READY_TO         200
   43 #define AL_SERDES_25G_RESET_TO                  100
   44 #define AL_SERDES_25G_RESET_NUM_RETRIES         5
   45 
   46 #if (!defined(AL_SERDES_BASIC_SERVICES_ONLY)) || (AL_SERDES_BASIC_SERVICES_ONLY == 0)
   47 #define AL_SRDS_ADV_SRVC(func)                  func
   48 #else
   49 static void al_serdes_hssp_stub_func(void)
   50 {
   51         al_err("%s: not implemented service called!\n", __func__);
   52 }
   53 
   54 #define AL_SRDS_ADV_SRVC(func)                  ((typeof(func) *)al_serdes_hssp_stub_func)
   55 #endif
   56 
   57 /******************************************************************************/
   58 /******************************************************************************/
   59 static enum al_serdes_type al_serdes_25g_type_get(void)
   60 {
   61         return AL_SRDS_TYPE_25G;
   62 }
   63 
   64 /******************************************************************************/
   65 /******************************************************************************/
   66 static int al_serdes_25g_reg_read(
   67         struct al_serdes_grp_obj        *obj,
   68         enum al_serdes_reg_page         page,
   69         enum al_serdes_reg_type         type,
   70         uint16_t                        offset,
   71         uint8_t                         *data)
   72 {
   73         struct al_serdes_c_regs __iomem *regs_base = obj->regs_base;
   74         uint32_t addr = 0;
   75 
   76         al_dbg("%s(%p, %d, %d, %u)\n", __func__, obj, page, type, offset);
   77 
   78         al_assert(obj);
   79         al_assert(data);
   80 
   81         switch (page) {
   82         case AL_SRDS_REG_PAGE_TOP:
   83                 addr = (SERDES_25G_TOP_BASE + offset);
   84                 break;
   85         case AL_SRDS_REG_PAGE_4_COMMON:
   86                 addr = (SERDES_25G_CM_BASE + offset);
   87                 break;
   88         case AL_SRDS_REG_PAGE_0_LANE_0:
   89         case AL_SRDS_REG_PAGE_1_LANE_1:
   90                 addr = (SERDES_25G_LANE_BASE + (page * SERDES_25G_LANE_SIZE) + offset);
   91                 break;
   92         default:
   93                 al_err("%s: wrong serdes type %d\n", __func__, type);
   94                 return -1;
   95         }
   96 
   97         al_reg_write32(&regs_base->gen.reg_addr, addr);
   98         *data = al_reg_read32(&regs_base->gen.reg_data);
   99 
  100         al_dbg("%s: return(%u)\n", __func__, *data);
  101 
  102         return 0;
  103 }
  104 
  105 static int al_serdes_25g_reg_write(
  106         struct al_serdes_grp_obj        *obj,
  107         enum al_serdes_reg_page         page,
  108         enum al_serdes_reg_type         type,
  109         uint16_t                        offset,
  110         uint8_t                         data)
  111 {
  112         struct al_serdes_c_regs __iomem *regs_base = obj->regs_base;
  113         uint32_t addr = 0;
  114 
  115         al_dbg("%s(%p, %d, %d, %u)\n", __func__, obj, page, type, offset);
  116 
  117         al_assert(obj);
  118 
  119         switch (page) {
  120         case AL_SRDS_REG_PAGE_TOP:
  121                 addr = (SERDES_25G_TOP_BASE + offset);
  122                 break;
  123         case AL_SRDS_REG_PAGE_4_COMMON:
  124                 addr = (SERDES_25G_CM_BASE + offset);
  125                 break;
  126         case AL_SRDS_REG_PAGE_0_LANE_0:
  127         case AL_SRDS_REG_PAGE_1_LANE_1:
  128                 addr = (SERDES_25G_LANE_BASE + (page * SERDES_25G_LANE_SIZE) + offset);
  129                 break;
  130         default:
  131                 al_err("%s: wrong serdes type %d\n", __func__, type);
  132                 return -1;
  133         }
  134 
  135         al_reg_write32(&regs_base->gen.reg_addr, addr);
  136         al_reg_write32(&regs_base->gen.reg_data, (data | SERDES_C_GEN_REG_DATA_STRB_MASK));
  137 
  138         al_dbg("%s: write(%u)\n", __func__, data);
  139 
  140         return 0;
  141 }
  142 
  143 /******************************************************************************/
  144 /******************************************************************************/
  145 static int al_serdes_25g_reg_masked_read(
  146         struct al_serdes_grp_obj        *obj,
  147         enum al_serdes_reg_page         page,
  148         uint16_t                        offset,
  149         uint8_t                         mask,
  150         uint8_t                         shift,
  151         uint8_t                         *data)
  152 {
  153         uint8_t val;
  154         int status = 0;
  155 
  156         status = al_serdes_25g_reg_read(obj, page, 0, offset, &val);
  157         if (status)
  158                 return status;
  159 
  160         *data = AL_REG_FIELD_GET(val, mask, shift);
  161 
  162         return 0;
  163 }
  164 
  165 static int al_serdes_25g_reg_masked_write(
  166         struct al_serdes_grp_obj        *obj,
  167         enum al_serdes_reg_page         page,
  168         uint16_t                        offset,
  169         uint8_t                         mask,
  170         uint8_t                         shift,
  171         uint8_t                         data)
  172 {
  173         uint8_t val;
  174         int status = 0;
  175 
  176         status = al_serdes_25g_reg_read(obj, page, 0, offset, &val);
  177         if (status)
  178                 return status;
  179 
  180         val &= (~mask);
  181         val |= (data << shift);
  182         return al_serdes_25g_reg_write(obj, page, 0, offset, val);
  183 }
  184 
  185 /******************************************************************************/
  186 /******************************************************************************/
  187 #define SERDES_25G_MB_RESP_BYTES        16
  188 #define SERDES_25G_MB_TIMEOUT           5000000 /* uSec */
  189 
  190 static int al_serdes_25g_mailbox_send_cmd(
  191         struct al_serdes_grp_obj        *obj,
  192         uint8_t                         cmd,
  193         uint8_t                         *data,
  194         uint8_t                         data_len)
  195 {
  196         uint8_t val;
  197         int i;
  198         uint32_t timeout = SERDES_25G_MB_TIMEOUT;
  199 
  200         if (data_len > AL_SERDES_MB_MAX_DATA_LEN) {
  201                 al_err("Cannot send command, data too long\n");
  202                 return -1;
  203         }
  204 
  205         /* Wait for CMD_FLAG to clear */
  206         while(1) {
  207                 al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0,
  208                                        SERDES_25G_TOP_CMD_FLAG_ADDR, &val);
  209                 if (val == 0)
  210                         break;
  211 
  212                 if (timeout == 0) {
  213                         al_err("%s: timeout occurred waiting to CMD_FLAG\n", __func__);
  214                         return -1;
  215                 }
  216 
  217                 timeout--;
  218                 al_udelay(1);
  219         }
  220 
  221         for (i = 0; i < data_len; i++) {
  222                 al_serdes_25g_reg_write(obj, AL_SRDS_REG_PAGE_TOP, 0,
  223                                         (SERDES_25G_TOP_CMD_DATA0_ADDR + i), data[i]);
  224         }
  225 
  226         /* this write will set CMD_FLAG automatically */
  227         al_serdes_25g_reg_write(obj, AL_SRDS_REG_PAGE_TOP, 0, SERDES_25G_TOP_CMD_ADDR, cmd);
  228 
  229         return 0;
  230 }
  231 
  232 static int al_serdes_25g_mailbox_recv_rsp(
  233         struct al_serdes_grp_obj        *obj,
  234         uint8_t                         *rsp_code,
  235         uint8_t                         *data,
  236         uint8_t                         *data_len)
  237 {
  238         uint8_t val;
  239         int i;
  240         uint32_t timeout = SERDES_25G_MB_TIMEOUT;
  241 
  242         /* wait for RSP_FLAG to set */
  243         while(1) {
  244                 al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0,
  245                                        SERDES_25G_TOP_RSP_FLAG_ADDR, &val);
  246                 if (val == 0x1)
  247                         break;
  248 
  249                 if (timeout == 0) {
  250                         al_err("%s: timeout occurred waiting to RSP_FLAG\n", __func__);
  251                         *data_len = 0;
  252                         return -1;
  253                 }
  254 
  255                 timeout--;
  256                 al_udelay(1);
  257         }
  258 
  259         /* Grab the response code and data */
  260         al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0,
  261                                 SERDES_25G_TOP_RSP_ADDR, rsp_code);
  262 
  263         for (i = 0; i < SERDES_25G_MB_RESP_BYTES; i++) {
  264                 al_serdes_25g_reg_read(obj, AL_SRDS_REG_PAGE_TOP, 0,
  265                                 (SERDES_25G_TOP_RSP_DATA0_ADDR + i), &data[i]);
  266         }
  267 
  268         /* clear the RSP_FLAG (write 1 to clear) */
  269         al_serdes_25g_reg_write(obj, AL_SRDS_REG_PAGE_TOP, 0,
  270                                 SERDES_25G_TOP_RSP_FLAG_ADDR, 0x1);
  271 
  272         *data_len = SERDES_25G_MB_RESP_BYTES;
  273 
  274         return 0;
  275 }
  276 
  277 /******************************************************************************/
  278 /******************************************************************************/
  279 static void al_serdes_25g_bist_rx_enable(
  280         struct al_serdes_grp_obj        *obj,
  281         enum al_serdes_lane             lane,
  282         al_bool                         enable)
  283 {
  284         if (enable) {
  285                 switch (lane) {
  286                 case 0:
  287                         al_serdes_25g_reg_masked_write(
  288                                         obj,
  289                                         AL_SRDS_REG_PAGE_TOP,
  290                                         SERDES_25G_TOP_CLOCK_LN0_CLK_RX_ADDR,
  291                                         SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_CG_EN_MASK,
  292                                         SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_CG_EN_SHIFT,
  293                                         0x1);
  294                         al_serdes_25g_reg_masked_write(
  295                                         obj,
  296                                         AL_SRDS_REG_PAGE_TOP,
  297                                         SERDES_25G_TOP_CLOCK_LN0_CLK_RX_ADDR,
  298                                         SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_BIST_CG_EN_MASK,
  299                                         SERDES_25G_TOP_CLOCK_LN0_CLK_RX_CTRL_BIST_CG_EN_SHIFT,
  300                                         0x1);
  301                         break;
  302                 case 1:
  303                         al_serdes_25g_reg_masked_write(
  304                                         obj,
  305                                         AL_SRDS_REG_PAGE_TOP,
  306                                         SERDES_25G_TOP_CLOCK_LN1_CLK_RX_ADDR,
  307                                         SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_CG_EN_MASK,
  308                                         SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_CG_EN_SHIFT,
  309                                         0x1);
  310 
  311                         al_serdes_25g_reg_masked_write(
  312                                         obj,
  313                                         AL_SRDS_REG_PAGE_TOP,
  314                                         SERDES_25G_TOP_CLOCK_LN1_CLK_RX_ADDR,
  315                                         SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_BIST_CG_EN_MASK,
  316                                         SERDES_25G_TOP_CLOCK_LN1_CLK_RX_CTRL_BIST_CG_EN_SHIFT,
  317                                         0x1);
  318                         break;
  319                 default:
  320                         al_err("%s: Wrong serdes lane %d\n", __func__, lane);
  321                         return;
  322                 }
  323 
  324                 al_serdes_25g_reg_masked_write(
  325                                 obj,
  326                                 (enum al_serdes_reg_page)lane,
  327                                 SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_ADDR,
  328                                 SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_STOP_ON_LOSS_LOCK_MASK,
  329                                 SERDES_25G_LANE_RX_BIST_LOSS_LOCK_CTRL4_STOP_ON_LOSS_LOCK_SHIFT,
  330                                 0);
  331                 al_serdes_25g_reg_masked_write(
  332                                 obj,
  333                                 (enum al_serdes_reg_page)lane,
  334                                 SERDES_25G_LANE_RX_BIST_CTRL_ADDR,
  335                                 SERDES_25G_LANE_RX_BIST_CTRL_EN_MASK,
  336                                 SERDES_25G_LANE_RX_BIST_CTRL_EN_SHIFT,
  337                                 1);
  338                 al_serdes_25g_reg_masked_write(
  339                                 obj,
  340                                 (enum al_serdes_reg_page)lane,
  341                                 SERDES_25G_LANE_RX_BIST_CTRL_ADDR,
  342                                 SERDES_25G_LANE_RX_BIST_CTRL_PATTERN_SEL_MASK,
  343                                 SERDES_25G_LANE_RX_BIST_CTRL_PATTERN_SEL_SHIFT,
  344                                 6);
  345         } else {
  346                 /* clear counters */
  347                 al_serdes_25g_reg_masked_write(
  348                                         obj,
  349                                         (enum al_serdes_reg_page)lane,
  350                                         SERDES_25G_LANE_RX_BIST_CTRL_ADDR,
  351                                         SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_MASK,
  352                                         SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_SHIFT,
  353                                         1);
  354 
  355                 al_serdes_25g_reg_masked_write(
  356                                         obj,
  357                                         (enum al_serdes_reg_page)lane,
  358                                         SERDES_25G_LANE_RX_BIST_CTRL_ADDR,
  359                                         SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_MASK,
  360                                         SERDES_25G_LANE_RX_BIST_CTRL_CLEAR_BER_SHIFT,
  361                                         0);
  362 
  363                 al_msleep(AL_SERDES_25G_WAIT_FOR_READY_TO);
  364 
  365                 /* disable */
  366                 al_serdes_25g_reg_masked_write(
  367                                 obj,
  368                                 (enum al_serdes_reg_page)lane,
  369                                 SERDES_25G_LANE_RX_BIST_CTRL_ADDR,
  370                                 SERDES_25G_LANE_RX_BIST_CTRL_EN_MASK,
  371                                 SERDES_25G_LANE_RX_BIST_CTRL_EN_SHIFT,
  372                                 0);
  373         }
  374 }
  375 
  376 // TODO: [Guy] change API to be per lane.
  377 static void al_serdes_25g_bist_pattern_select(
  378         struct al_serdes_grp_obj        *obj,
  379         enum al_serdes_bist_pattern     pattern,
  380         uint8_t                         *user_data)
  381 {
  382         enum al_serdes_lane lane;
  383         uint8_t val = 0;
  384 
  385         switch (pattern) {
  386         case AL_SRDS_BIST_PATTERN_USER:
  387                 al_assert(user_data);
  388                 val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS_USER;
  389                 break;
  390         case AL_SRDS_BIST_PATTERN_PRBS7:
  391                 val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS7;
  392                 break;
  393         case AL_SRDS_BIST_PATTERN_PRBS23:
  394                 val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS23;
  395                 break;
  396         case AL_SRDS_BIST_PATTERN_PRBS31:
  397                 val = SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_PRBS31;
  398                 break;
  399         case AL_SRDS_BIST_PATTERN_CLK1010:
  400         default:
  401                 al_err("%s: invalid pattern (%d)\n", __func__, pattern);
  402                 al_assert(0);
  403         }
  404 
  405         for (lane = AL_SRDS_LANE_0; lane <= AL_SRDS_LANE_1; lane++) {
  406                 if (pattern == AL_SRDS_BIST_PATTERN_USER) {
  407                         int i;
  408 
  409                         for (i = 0; i < SERDES_25G_LANE_TX_BIST_UDP_NUM_BYTES; i++)
  410                                 al_serdes_25g_reg_write(
  411                                                 obj,
  412                                                 (enum al_serdes_reg_page)lane,
  413                                                 0,
  414                                                 SERDES_25G_LANE_TX_BIST_UDP_ADDR(i),
  415                                                 user_data[i]);
  416                 }
  417 
  418                 al_serdes_25g_reg_masked_write(
  419                                         obj,
  420                                         (enum al_serdes_reg_page)lane,
  421                                         SERDES_25G_LANE_TX_BIST_CTRL_ADDR,
  422                                         SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_SEL_MASK,
  423                                         SERDES_25G_LANE_TX_BIST_CTRL_PATTERN_SEL_SHIFT,
  424                                         val);
  425         }
  426 }
  427 
  428 static void al_serdes_25g_bist_tx_enable(
  429         struct al_serdes_grp_obj        *obj,
  430         enum al_serdes_lane             lane,
  431         al_bool                         enable)
  432 {
  433         if (enable) {
  434                 al_serdes_25g_reg_masked_write(
  435                                         obj,
  436                                         (enum al_serdes_reg_page)lane,
  437                                         SERDES_25G_LANE_TX_BIST_CTRL_ADDR,
  438                                         SERDES_25G_LANE_TX_BIST_CTRL_EN_MASK,
  439                                         SERDES_25G_LANE_TX_BIST_CTRL_EN_SHIFT,
  440                                         0x1);
  441                 al_serdes_25g_reg_masked_write(
  442                                         obj,
  443                                         (enum al_serdes_reg_page)lane,
  444                                         SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_ADDR,
  445                                         SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_MASK,
  446                                         SERDES_25G_LANE_TOP_DPL_TXDP_CTRL1_DMUX_TXA_SEL_SHIFT,
  447                                         0x2);
  448 
  449                 switch (lane) {
  450                 case AL_SRDS_LANE_0:
  451                         al_serdes_25g_reg_masked_write(
  452                                         obj,
  453                                         AL_SRDS_REG_PAGE_TOP,
  454                                         SERDES_25G_TOP_CLOCK_LN0_CLK_TX_ADDR,
  455                                         SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_BIST_CG_EN_MASK,
  456                                         SERDES_25G_TOP_CLOCK_LN0_CLK_TX_CTRL_BIST_CG_EN_SHIFT,
  457                                         0x1);
  458                         break;
  459                 case AL_SRDS_LANE_1:
  460                         al_serdes_25g_reg_masked_write(
  461                                         obj,
  462                                         AL_SRDS_REG_PAGE_TOP,
  463                                         SERDES_25G_TOP_CLOCK_LN1_CLK_TX_ADDR,
  464                                         SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_BIST_CG_EN_MASK,
  465                                         SERDES_25G_TOP_CLOCK_LN1_CLK_TX_CTRL_BIST_CG_EN_SHIFT,
  466                                         0x1);
  467                         break;
  468                 default:
  469                         al_err("%s: Wrong serdes lane %d\n", __func__, lane);
  470                                 return;
  471                 }
  472         } else {
  473                 al_serdes_25g_reg_masked_write(
  474                                         obj,
  475                                         (enum al_serdes_reg_page)lane,
  476                                         SERDES_25G_LANE_TX_BIST_CTRL_ADDR,
  477                                         SERDES_25G_LANE_TX_BIST_CTRL_EN_MASK,
  478                                         SERDES_25G_LANE_TX_BIST_CTRL_EN_SHIFT,
  479                                         0);
  480         }
  481 
  482 }
  483 
  484 static void al_serdes_25g_bist_rx_status(
  485         struct al_serdes_grp_obj        *obj,
  486         enum al_serdes_lane             lane,
  487         al_bool                         *is_locked,
  488         al_bool                         *err_cnt_overflow,
  489         uint32_t                        *err_cnt)
  490 {
  491         uint8_t status;
  492         uint8_t err1;
  493         uint8_t err2;
  494         uint8_t err3;
  495 
  496         al_serdes_25g_reg_masked_read(
  497                 obj,
  498                 (enum al_serdes_reg_page)lane,
  499                 SERDES_25G_LANE_RX_BIST_STATUS_ADDR,
  500                 SERDES_25G_LANE_RX_BIST_STATUS_STATE_MASK,
  501                 SERDES_25G_LANE_RX_BIST_STATUS_STATE_SHIFT,
  502                 &status);
  503 
  504         if (status != 3) {
  505                 *is_locked = AL_FALSE;
  506                 return;
  507         }
  508 
  509         *is_locked = AL_TRUE;
  510         *err_cnt_overflow = AL_FALSE;
  511 
  512         al_serdes_25g_reg_masked_read(
  513                 obj,
  514                 (enum al_serdes_reg_page)lane,
  515                 SERDES_25G_LANE_RX_BIST_BER_STATUS0_ADDR,
  516                 SERDES_25G_LANE_RX_BIST_BER_STATUS0_BIT_ERROR_COUNT_7_0_MASK,
  517                 SERDES_25G_LANE_RX_BIST_BER_STATUS0_BIT_ERROR_COUNT_7_0_SHIFT,
  518                 &err1);
  519 
  520         al_serdes_25g_reg_masked_read(
  521                 obj,
  522                 (enum al_serdes_reg_page)lane,
  523                 SERDES_25G_LANE_RX_BIST_BER_STATUS1_ADDR,
  524                 SERDES_25G_LANE_RX_BIST_BER_STATUS1_BIT_ERROR_COUNT_15_8_MASK,
  525                 SERDES_25G_LANE_RX_BIST_BER_STATUS1_BIT_ERROR_COUNT_15_8_SHIFT,
  526                 &err2);
  527 
  528         al_serdes_25g_reg_masked_read(
  529                 obj,
  530                 (enum al_serdes_reg_page)lane,
  531                 SERDES_25G_LANE_RX_BIST_BER_STATUS2_ADDR,
  532                 SERDES_25G_LANE_RX_BIST_BER_STATUS2_BIT_ERROR_COUNT_23_16_MASK,
  533                 SERDES_25G_LANE_RX_BIST_BER_STATUS2_BIT_ERROR_COUNT_23_16_SHIFT,
  534                 &err3);
  535 
  536         *err_cnt = (err1 + (err2 << 8) + (err3 << 16));
  537 }
  538 
  539 #define SERDES_MB_CMD_SWING_CFG         0x83
  540 #define SERDES_MB_CMD_SAMPLES_COUNT     0x84
  541 #define SERDES_MB_CMD_START_MEASURE     0x82
  542 
  543 #define SERDES_MB_RSP_CODE_0            0
  544 #define SERDES_MB_RSP_CODE_1            1
  545 #define SERDES_MB_RSP_CODE_2            2
  546 
  547 static int al_serdes_25g_eye_diag_run(
  548         struct al_serdes_grp_obj        *obj,
  549         enum al_serdes_lane             lane,
  550         int                             x_start,
  551         int                             x_stop,
  552         unsigned int                    x_step,
  553         int                             y_start,
  554         int                             y_stop,
  555         unsigned int                    y_step,
  556         uint64_t                        ber_target,
  557         uint64_t                        *buf,
  558         uint32_t                        buf_size)
  559 {
  560         int rc;
  561         uint8_t rsp_code;
  562         uint8_t data[16];
  563         uint8_t data_len;
  564         uint32_t total_bits;
  565         uint8_t bits_left_curr_sample;
  566         uint8_t bits_left_curr_byte;
  567         uint32_t byte = 0;
  568         uint32_t x = 0;
  569         uint32_t x_samples = (((x_stop - x_start) / x_step) + 1);
  570         uint32_t y = 0;
  571         uint32_t y_samples = (((y_stop - y_start) / y_step) + 1);
  572         uint8_t sample_width = (64 - __builtin_clzl(ber_target));
  573         uint8_t msb;
  574         uint8_t lsb;
  575         uint32_t samples_left = ((x_samples * y_samples));
  576         uint8_t sign = 0;
  577 
  578         al_assert(buf_size == (samples_left * sizeof(uint64_t)));
  579 
  580         al_memset(buf, 0, buf_size);
  581 
  582         if (y_start < 0) {
  583                 y_start *= -1;
  584                 sign |= 0x1;
  585         }
  586 
  587         if (y_stop < 0) {
  588                 y_stop *= -1;
  589                 sign |= 0x2;
  590         }
  591 
  592         data[0] = lane;
  593         data[1] = x_start;
  594         data[2] = x_stop;
  595         data[3] = x_step;
  596         data[4] = y_start;
  597         data[5] = y_stop;
  598         data[6] = sign;
  599         data[7] = y_step;
  600 
  601         rc = al_serdes_25g_mailbox_send_cmd(
  602                                 obj,
  603                                 SERDES_MB_CMD_SWING_CFG,
  604                                 data,
  605                                 8);
  606 
  607         if (rc) {
  608                 al_err("%s: Failed to send command %d to mailbox.\n",
  609                         __func__, SERDES_MB_CMD_SWING_CFG);
  610                 return rc;
  611         }
  612 
  613         rc = al_serdes_25g_mailbox_recv_rsp(
  614                                 obj,
  615                                 &rsp_code,
  616                                 data,
  617                                 &data_len);
  618 
  619         if ((rc) || (rsp_code != SERDES_MB_RSP_CODE_0)) {
  620                 al_err("%s: Failed to send command %d to mailbox. rsp_code %d\n",
  621                         __func__, SERDES_MB_CMD_SWING_CFG, rsp_code);
  622 
  623                 return (ETIMEDOUT);
  624         }
  625 
  626         al_assert(sample_width <= 40);
  627 
  628         data[0] = lane;
  629         data[1] = ((ber_target >> 32) & 0xFF);
  630         data[2] = ((ber_target >> 24) & 0xFF);
  631         data[3] = ((ber_target >> 16) & 0xFF);
  632         data[4] = ((ber_target >> 8) & 0xFF);
  633         data[5] = (ber_target & 0xFF);
  634 
  635         rc = al_serdes_25g_mailbox_send_cmd(
  636                                 obj,
  637                                 SERDES_MB_CMD_SAMPLES_COUNT,
  638                                 data,
  639                                 6);
  640 
  641         if (rc) {
  642                 al_err("%s: Failed to send command %d to mailbox.\n",
  643                         __func__, SERDES_MB_CMD_SAMPLES_COUNT);
  644                 return rc;
  645         }
  646 
  647         rc = al_serdes_25g_mailbox_recv_rsp(
  648                                 obj,
  649                                 &rsp_code,
  650                                 data,
  651                                 &data_len);
  652 
  653         if ((rc) || (rsp_code != SERDES_MB_RSP_CODE_0)) {
  654                 al_err("%s: Failed to send command %d to mailbox. rsp_code %d\n",
  655                         __func__, SERDES_MB_CMD_SAMPLES_COUNT, rsp_code);
  656 
  657                 return (ETIMEDOUT);
  658         }
  659 
  660         rc = al_serdes_25g_mailbox_send_cmd(
  661                                 obj,
  662                                 SERDES_MB_CMD_START_MEASURE,
  663                                 data,
  664                                 0);
  665 
  666         bits_left_curr_sample = sample_width;
  667 
  668         while (rsp_code != SERDES_MB_RSP_CODE_1) {
  669                 uint8_t num_bits = 0;
  670 
  671                 rc = al_serdes_25g_mailbox_recv_rsp(
  672                                 obj,
  673                                 &rsp_code,
  674                                 data,
  675                                 &data_len);
  676 
  677                 if ((rc != 0) || (rsp_code > SERDES_MB_RSP_CODE_2)) {
  678                         al_err("%s: command %d return failure. rsp_code %d\n",
  679                         __func__, SERDES_MB_CMD_START_MEASURE, rsp_code);
  680 
  681                         return (ETIMEDOUT);
  682                 }
  683                 byte = 0;
  684                 total_bits = data_len * 8;
  685                 bits_left_curr_byte = 8;
  686                 while (total_bits > 0) {
  687                         num_bits = al_min_t(uint8_t, bits_left_curr_sample, bits_left_curr_byte);
  688 
  689                         buf[(y * x_samples) + x] <<= num_bits;
  690                         msb = bits_left_curr_byte - 1;
  691                         lsb = msb - num_bits + 1;
  692                         buf[(y * x_samples) + x] |= (data[byte] & AL_FIELD_MASK(msb, lsb) >> lsb);
  693 
  694                         total_bits -= num_bits;
  695 
  696                         bits_left_curr_byte -= num_bits;
  697                         if (!bits_left_curr_byte) {
  698                                 bits_left_curr_byte = 8;
  699                                 byte++;
  700                         }
  701 
  702                         bits_left_curr_sample -= num_bits;
  703                         if (!bits_left_curr_sample) {
  704                                 y++;
  705                                 if (y == y_samples) {
  706                                         y = 0;
  707                                         x++;
  708                                 }
  709 
  710                                 samples_left--;
  711                                 bits_left_curr_sample = sample_width;
  712                         }
  713 
  714                         if (samples_left == 0)
  715                                 break;
  716                 }
  717 
  718                 if ((samples_left == 0) && (rsp_code != SERDES_MB_RSP_CODE_1)) {
  719                         rc = al_serdes_25g_mailbox_recv_rsp(
  720                                                 obj,
  721                                                 &rsp_code,
  722                                                 data,
  723                                                 &data_len);
  724                         if ((rc) || (rsp_code == SERDES_MB_RSP_CODE_0)) {
  725                                 al_err("%s: Parsed enough samples but f/w is still sending more\n",
  726                                         __func__);
  727 
  728                                 return -EIO;
  729                         }
  730                         break;
  731                 }
  732         }
  733 
  734         if (samples_left > 0) {
  735                 al_err("%s: Still need more samples but f/w has stopped sending them!?!?!?\n",
  736                         __func__);
  737 
  738                 return -EIO;
  739         }
  740 
  741         return 0;
  742 }
  743 
  744 #define SERDES_25G_EYE_X_MIN            1
  745 #define SERDES_25G_EYE_X_MAX            127
  746 #define SERDES_25G_EYE_Y_MIN            -200
  747 #define SERDES_25G_EYE_Y_MAX            200
  748 #define SERDES_25G_EYE_SIZE_MAX_SAMPLES 401
  749 #define SERDES_25G_EYE_SIZE_BER_TARGET  0xffff
  750 #define SERDES_25G_EYE_SIZE_ERR_TH      10
  751 
  752 static int al_serdes_25g_calc_eye_size(
  753                 struct al_serdes_grp_obj        *obj,
  754                 enum al_serdes_lane             lane,
  755                 int                             *width,
  756                 int                             *height)
  757 {
  758         uint64_t samples[SERDES_25G_EYE_SIZE_MAX_SAMPLES];
  759         int i;
  760         int _width = 0;
  761         int _height = 0;
  762         int rc;
  763         int mid_x = ((SERDES_25G_EYE_X_MIN + SERDES_25G_EYE_X_MAX) / 2);
  764         int mid_y = ((SERDES_25G_EYE_Y_MIN + SERDES_25G_EYE_Y_MAX) / 2);
  765 
  766         *height = 0;
  767         *width = 0;
  768 
  769         rc = al_serdes_25g_eye_diag_run(obj,
  770                                         lane,
  771                                         mid_x,
  772                                         mid_x,
  773                                         1,
  774                                         SERDES_25G_EYE_Y_MIN,
  775                                         SERDES_25G_EYE_Y_MAX,
  776                                         1,
  777                                         SERDES_25G_EYE_SIZE_BER_TARGET,
  778                                         samples,
  779                                         ((SERDES_25G_EYE_Y_MAX - SERDES_25G_EYE_Y_MIN + 1) *
  780                                           sizeof(uint64_t)));
  781 
  782         if (rc) {
  783                 al_err("%s: failed to run eye_diag\n", __func__);
  784                 return rc;
  785         }
  786 
  787         for (i = (mid_y - SERDES_25G_EYE_Y_MIN);
  788                 ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) &&
  789                         (i < (SERDES_25G_EYE_Y_MAX - SERDES_25G_EYE_Y_MIN + 1)));
  790                 i++, (_height)++)
  791                 ;
  792         for (i = (mid_y - SERDES_25G_EYE_Y_MIN);
  793                 ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) && (i >= 0));
  794                 i--, (_height)++)
  795                 ;
  796 
  797         rc = al_serdes_25g_eye_diag_run(obj,
  798                                         lane,
  799                                         SERDES_25G_EYE_X_MIN,
  800                                         SERDES_25G_EYE_X_MAX,
  801                                         1,
  802                                         mid_y,
  803                                         mid_y,
  804                                         1,
  805                                         SERDES_25G_EYE_SIZE_BER_TARGET,
  806                                         samples,
  807                                         ((SERDES_25G_EYE_X_MAX - SERDES_25G_EYE_X_MIN + 1) *
  808                                           sizeof(uint64_t)));
  809 
  810         if (rc) {
  811                 al_err("%s: failed to run eye_diag\n", __func__);
  812                 return rc;
  813         }
  814 
  815         for (i = (mid_x - SERDES_25G_EYE_X_MIN);
  816                 ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) &&
  817                         (i < (SERDES_25G_EYE_X_MAX - SERDES_25G_EYE_X_MIN + 1)));
  818                 i++, (_width)++)
  819                 ;
  820         for (i = (mid_x - SERDES_25G_EYE_X_MIN);
  821                 ((samples[i] < SERDES_25G_EYE_SIZE_ERR_TH) && (i >= 0));
  822                 i--, (_width)++)
  823                 ;
  824 
  825         *height = _height;
  826         *width = _width;
  827 
  828         return 0;
  829 }
  830 
  831 
  832 static void al_serdes_25g_tx_advanced_params_set(struct al_serdes_grp_obj       *obj,
  833                                         enum al_serdes_lane                     lane,
  834                                         void                                    *tx_params)
  835 {
  836         struct al_serdes_adv_tx_params  *params = tx_params;
  837         uint32_t timeout = 5000;
  838         uint8_t val = 0;
  839 
  840         al_serdes_25g_reg_masked_write(obj,
  841                                         (enum al_serdes_reg_page)lane,
  842                                         SERDES_25G_LANE_DRV_TXEQ_CTRL3_ADDR,
  843                                         SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_MASK,
  844                                         SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_SHIFT,
  845                                         params->c_minus_1);
  846 
  847         al_serdes_25g_reg_masked_write(obj,
  848                                         (enum al_serdes_reg_page)lane,
  849                                         SERDES_25G_LANE_DRV_TXEQ_CTRL1_ADDR,
  850                                         SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_MASK,
  851                                         SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_SHIFT,
  852                                         params->c_plus_1);
  853 
  854         al_serdes_25g_reg_masked_write(obj,
  855                                         (enum al_serdes_reg_page)lane,
  856                                         SERDES_25G_LANE_DRV_TXEQ_CTRL5_ADDR,
  857                                         SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_MASK,
  858                                         SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_SHIFT,
  859                                         params->total_driver_units);
  860 
  861         al_serdes_25g_reg_masked_write(obj,
  862                                         (enum al_serdes_reg_page)lane,
  863                                         SERDES_25G_LANE_DRV_TXEQ_CTRL0_ADDR,
  864                                         SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_MASK,
  865                                         SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_SHIFT,
  866                                         1);
  867 
  868 
  869         /* wait for acknowledge */
  870         while (1) {
  871                 al_serdes_25g_reg_masked_read(obj,
  872                                         (enum al_serdes_reg_page)lane,
  873                                         SERDES_25G_LANE_DRV_TXEQ_STATUS0_ADDR,
  874                                         SERDES_25G_LANE_DRV_TXEQ_STATUS0_ACK_MASK,
  875                                         SERDES_25G_LANE_DRV_TXEQ_STATUS0_ACK_SHIFT,
  876                                         &val);
  877                 if (val == 1)
  878                         break;
  879 
  880                 if (timeout == 0) {
  881                         al_err("%s: timeout occurred waiting to FW ack\n", __func__);
  882                         break;
  883                 }
  884 
  885                 timeout--;
  886                 al_udelay(1);
  887         }
  888 
  889         al_serdes_25g_reg_masked_write(obj,
  890                                         (enum al_serdes_reg_page)lane,
  891                                         SERDES_25G_LANE_DRV_TXEQ_CTRL0_ADDR,
  892                                         SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_MASK,
  893                                         SERDES_25G_LANE_DRV_TXEQ_CTRL0_REQ_SHIFT,
  894                                         0);
  895 }
  896 
  897 static void al_serdes_25g_tx_advanced_params_get(struct al_serdes_grp_obj       *obj,
  898                 enum al_serdes_lane                     lane,
  899                 void                                    *tx_params)
  900 {
  901         struct al_serdes_adv_tx_params  *params = tx_params;
  902 
  903         al_serdes_25g_reg_masked_read(obj,
  904                                         (enum al_serdes_reg_page)lane,
  905                                         SERDES_25G_LANE_DRV_TXEQ_CTRL3_ADDR,
  906                                         SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_MASK,
  907                                         SERDES_25G_LANE_DRV_TXEQ_CTRL3_TXEQ_CM1_SHIFT,
  908                                         &params->c_minus_1);
  909 
  910         al_serdes_25g_reg_masked_read(obj,
  911                                         (enum al_serdes_reg_page)lane,
  912                                         SERDES_25G_LANE_DRV_TXEQ_CTRL1_ADDR,
  913                                         SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_MASK,
  914                                         SERDES_25G_LANE_DRV_TXEQ_CTRL1_TXEQ_C1_SHIFT,
  915                                         &params->c_plus_1);
  916 
  917         al_serdes_25g_reg_masked_read(obj,
  918                                         (enum al_serdes_reg_page)lane,
  919                                         SERDES_25G_LANE_DRV_TXEQ_CTRL5_ADDR,
  920                                         SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_MASK,
  921                                         SERDES_25G_LANE_DRV_TXEQ_CTRL5_DRV_SWING_SHIFT,
  922                                         &params->total_driver_units);
  923 }
  924 
  925 static al_bool al_serdes_25g_cdr_is_locked(
  926                 struct al_serdes_grp_obj        *obj,
  927                 enum al_serdes_lane             lane)
  928 {
  929         uint8_t reg;
  930 
  931         al_serdes_25g_reg_masked_read(obj,
  932                                 (enum al_serdes_reg_page)lane,
  933                                 SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_ADDR,
  934                                 SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_LOCKED_MASK,
  935                                 SERDES_25G_LANE_CDR_RXCLK_DLPF_STATUS5_LOCKED_SHIFT,
  936                                 &reg);
  937 
  938         return !!reg;
  939 
  940 }
  941 
  942 static al_bool al_serdes_25g_rx_valid(
  943                 struct al_serdes_grp_obj        *obj,
  944                 enum al_serdes_lane             lane)
  945 {
  946         uint8_t reg;
  947 
  948         al_serdes_25g_reg_masked_read(obj,
  949                                 (enum al_serdes_reg_page)lane,
  950                                 SERDES_25G_LANE_TOP_LN_STAT_CTRL0_ADDR,
  951                                 SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_MASK,
  952                                 SERDES_25G_LANE_TOP_LN_STAT_CTRL0_RXVALID_SHIFT,
  953                                 &reg);
  954 
  955         return !!reg;
  956 
  957 }
  958 
  959 static al_bool al_serdes_25g_signal_is_detected(
  960                 struct al_serdes_grp_obj        *obj,
  961                 enum al_serdes_lane             lane)
  962 {
  963         struct al_serdes_c_regs __iomem *regs_base = obj->regs_base;
  964         uint32_t reg;
  965         al_bool signal_detect = AL_FALSE;
  966 
  967         reg = al_reg_read32(&regs_base->lane[lane].stat);
  968 
  969         signal_detect = ((reg & (SERDES_C_LANE_STAT_LN_STAT_LOS |
  970                                  SERDES_C_LANE_STAT_LN_STAT_LOS_DEGLITCH)) ?
  971                                         AL_FALSE : AL_TRUE);
  972 
  973         return signal_detect;
  974 
  975 }
  976 
  977 static int al_serdes_25g_rx_equalization(
  978                 struct al_serdes_grp_obj        *obj,
  979                 enum al_serdes_lane             lane)
  980 {
  981         struct al_serdes_c_regs __iomem *regs_base = obj->regs_base;
  982         uint32_t ready_mask = (SERDES_C_GEN_STATUS_CM0_RST_PD_READY | SERDES_C_GEN_STATUS_CM0_OK_O);
  983         uint32_t reset_mask;
  984         uint32_t timeout;
  985         uint32_t reg_val;
  986         uint32_t retries = AL_SERDES_25G_RESET_NUM_RETRIES;
  987         int status = 0;
  988 
  989         if (lane == 0) {
  990                 ready_mask |= SERDES_C_GEN_STATUS_LN0_RST_PD_READY;
  991                 reset_mask = SERDES_C_GEN_RST_LN0_RST_N;
  992         } else {
  993                 ready_mask |= SERDES_C_GEN_STATUS_LN1_RST_PD_READY;
  994                 reset_mask = SERDES_C_GEN_RST_LN1_RST_N;
  995         }
  996 
  997         while (retries > 0) {
  998                 timeout = AL_SERDES_25G_WAIT_FOR_READY_TO;
  999                 status = 0;
 1000 
 1001                 al_reg_write32_masked(&regs_base->gen.rst, reset_mask, 0);
 1002 
 1003                 al_msleep(AL_SERDES_25G_RESET_TO);
 1004 
 1005                 al_serdes_25g_reg_masked_write(obj,
 1006                                         (enum al_serdes_reg_page)lane,
 1007                                         SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_ADDR,
 1008                                         SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT0_EN_MASK,
 1009                                         SERDES_25G_LANE_FEATURE_CTLE_ADAPT_MBS_CFG_INIT0_EN_SHIFT,
 1010                                         0);
 1011 
 1012                 al_serdes_25g_reg_masked_write(obj,
 1013                                         (enum al_serdes_reg_page)lane,
 1014                                         SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_ADDR,
 1015                                         SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBF_START_MASK,
 1016                                         SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBF_START_SHIFT,
 1017                                         7);
 1018 
 1019                 al_serdes_25g_reg_masked_write(obj,
 1020                                         (enum al_serdes_reg_page)lane,
 1021                                         SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_ADDR,
 1022                                         SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBG_START_MASK,
 1023                                         SERDES_25G_LANE_LEQ_REFCLK_EQ_MB_CTRL1_EQ_MBG_START_SHIFT,
 1024                                         15);
 1025 
 1026                 al_msleep(AL_SERDES_25G_RESET_TO);
 1027 
 1028                 al_reg_write32_masked(&regs_base->gen.rst, reset_mask, reset_mask);
 1029 
 1030                 while (1) {
 1031                         reg_val = al_reg_read32(&regs_base->gen.status);
 1032                         if ((reg_val & ready_mask) == ready_mask)
 1033                                 break;
 1034 
 1035                         al_udelay(1);
 1036                         timeout--;
 1037 
 1038                         if (timeout == 0) {
 1039                                 al_err("%s: Timeout waiting for serdes ready\n", __func__);
 1040                                 status = ETIMEDOUT;
 1041                                 retries--;
 1042                                 break;
 1043                         }
 1044                 }
 1045 
 1046                 if (status)
 1047                         continue;
 1048 
 1049                 while (1) {
 1050                         reg_val = al_reg_read32(&regs_base->lane[lane].stat);
 1051                         reg_val &= (SERDES_C_LANE_STAT_LNX_STAT_OK |
 1052                                     SERDES_C_LANE_STAT_LN_STAT_RXVALID);
 1053                         if (reg_val == (SERDES_C_LANE_STAT_LNX_STAT_OK |
 1054                                         SERDES_C_LANE_STAT_LN_STAT_RXVALID))
 1055                                 break;
 1056 
 1057                         al_udelay(1);
 1058                         timeout--;
 1059 
 1060                         if (timeout == 0) {
 1061                                 al_err("%s: TO waiting for lane ready (%x)\n", __func__, reg_val);
 1062                                 status = ETIMEDOUT;
 1063                                 retries--;
 1064                                 break;
 1065                         }
 1066                 }
 1067 
 1068                 if (status)
 1069                         continue;
 1070 
 1071                 break;
 1072         }
 1073 
 1074         if (retries == 0) {
 1075                 al_err("%s: Failed to run equalization\n", __func__);
 1076                 status = ETIMEDOUT;
 1077         }
 1078 
 1079         return status;
 1080 
 1081 }
 1082 
 1083 #define AL_SERDES_25G_GCFSM2_READ_TIMEOUT               2000000 /* uSec */
 1084 
 1085 static int al_serdes_25g_gcfsm2_read(
 1086                 struct al_serdes_grp_obj        *obj,
 1087                 enum al_serdes_lane             lane,
 1088                 uint8_t                 offset,
 1089                 uint16_t                *data)
 1090 {
 1091         int status = 0;
 1092         uint32_t timeout = AL_SERDES_25G_GCFSM2_READ_TIMEOUT;
 1093         uint8_t ack = 0;
 1094         uint8_t data_low, data_high;
 1095 
 1096         al_assert(data);
 1097 
 1098         /* Make sure GCFSM2 REQuest is off */
 1099         al_serdes_25g_reg_masked_write(
 1100                         obj,
 1101                         (enum al_serdes_reg_page)lane,
 1102                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_ADDR,
 1103                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_MASK,
 1104                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_SHIFT,
 1105                         0);
 1106         /* Write GCFSM2 CMD; CMD=0 for Read Request */
 1107         al_serdes_25g_reg_masked_write(
 1108                         obj,
 1109                         (enum al_serdes_reg_page)lane,
 1110                         SERDES_25G_LANE_GCFSM2_CMD_CTRL1_ADDR,
 1111                         SERDES_25G_LANE_GCFSM2_CMD_CTRL1_CMD_MASK,
 1112                         SERDES_25G_LANE_GCFSM2_CMD_CTRL1_CMD_SHIFT,
 1113                         0);
 1114         /* Write GCFSM2 the Address we wish to read */
 1115         al_serdes_25g_reg_write(
 1116                         obj,
 1117                         (enum al_serdes_reg_page)lane,
 1118                         0,
 1119                         SERDES_25G_LANE_GCFSM2_CMD_CTRL2_ADDR,
 1120                         offset);
 1121         /* Issue a command REQuest */
 1122         al_serdes_25g_reg_masked_write(
 1123                         obj,
 1124                         (enum al_serdes_reg_page)lane,
 1125                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_ADDR,
 1126                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_MASK,
 1127                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_SHIFT,
 1128                         1);
 1129         /* Poll on GCFSM2 ACK */
 1130         while (1) {
 1131                 al_serdes_25g_reg_masked_read(
 1132                                 obj,
 1133                                 (enum al_serdes_reg_page)lane,
 1134                                 SERDES_25G_LANE_GCFSM2_CMD_STATUS_ADDR,
 1135                                 SERDES_25G_LANE_GCFSM2_CMD_STATUS_ACK_MASK,
 1136                                 SERDES_25G_LANE_GCFSM2_CMD_STATUS_ACK_SHIFT,
 1137                                 &ack);
 1138 
 1139                 if (ack || (timeout == 0))
 1140                         break;
 1141 
 1142                 timeout--;
 1143                 al_udelay(1);
 1144         }
 1145 
 1146         if (ack) {
 1147                 /* Read 12bit of register value */
 1148                 al_serdes_25g_reg_read(
 1149                                 obj,
 1150                                 (enum al_serdes_reg_page)lane,
 1151                                 0,
 1152                                 SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS0_ADDR,
 1153                                 &data_low);
 1154                 al_serdes_25g_reg_masked_read(
 1155                                 obj,
 1156                                 (enum al_serdes_reg_page)lane,
 1157                                 SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_ADDR,
 1158                                 SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_11_8_MASK,
 1159                                 SERDES_25G_LANE_GCFSM2_READ_SHADOW_DATA_STATUS1_11_8_SHIFT,
 1160                                 &data_high);
 1161                 *data = (data_high << 8) | data_low;
 1162         } else {
 1163                 al_err("%s: TO waiting for GCFSM2 req to complete (%x)\n", __func__, offset);
 1164                 status = ETIMEDOUT;
 1165         }
 1166 
 1167         /* Deassert the GCFSM2 REQuest */
 1168         al_serdes_25g_reg_masked_write(
 1169                         obj,
 1170                         (enum al_serdes_reg_page)lane,
 1171                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_ADDR,
 1172                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_MASK,
 1173                         SERDES_25G_LANE_GCFSM2_CMD_CTRL0_REQ_SHIFT,
 1174                         0);
 1175 
 1176         return status;
 1177 }
 1178 
 1179 enum al_serdes_25g_rx_leq_fsm_opcode {
 1180         AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ            = 0x1,
 1181         AL_SERDES_25G_RX_LEQ_FSM_OPCODE_WRITE           = 0x2,
 1182 };
 1183 
 1184 enum al_serdes_25g_rx_leq_fsm_target {
 1185         AL_SERDES_25G_RX_LEQ_FSM_TARGET_AGC_SOURCE              = 0x1,
 1186         AL_SERDES_25G_RX_LEQ_FSM_TARGET_PLE_ATT                 = 0x2,
 1187         AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_LFG                  = 0x3,
 1188         AL_SERDES_25G_RX_LEQ_FSM_TARGET_GN_APG                  = 0x4,
 1189         AL_SERDES_25G_RX_LEQ_FSM_TARGET_GNEQ_CCL_LFG    = 0x5,
 1190         AL_SERDES_25G_RX_LEQ_FSM_TARGET_HFG_SQL                 = 0x6,
 1191         AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBF                  = 0x8,
 1192         AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBG                  = 0x9,
 1193         AL_SERDES_25G_RX_LEQ_FSM_TARGET_VSCAN                   = 0xA,
 1194         AL_SERDES_25G_RX_LEQ_FSM_TARGET_HSCAN                   = 0xB,
 1195         AL_SERDES_25G_RX_LEQ_FSM_TARGET_EYE_INTF                = 0xC,
 1196 };
 1197 
 1198 #define AL_SERDES_25G_RX_LEQ_FSM_TIMEOUT                2000000 /* uSec */
 1199 
 1200 static int al_serdes_25g_rx_leq_fsm_op(
 1201                 struct al_serdes_grp_obj        *obj,
 1202                 enum al_serdes_lane     lane,
 1203                 enum al_serdes_25g_rx_leq_fsm_opcode    opcode,
 1204                 enum al_serdes_25g_rx_leq_fsm_target    target,
 1205                 uint8_t val,
 1206                 uint8_t *data,
 1207                 uint8_t *err)
 1208 {
 1209         uint32_t reg;
 1210         uint32_t timeout = AL_SERDES_25G_RX_LEQ_FSM_TIMEOUT;
 1211         uint8_t ack = 0;
 1212         int status = 0;
 1213 
 1214         al_assert(data);
 1215         al_assert(err);
 1216 
 1217         /* Write the OpCode & Target to LEQ FSM */
 1218         reg = (target << 4) | opcode;
 1219         al_serdes_25g_reg_write(
 1220                         obj,
 1221                         (enum al_serdes_reg_page)lane,
 1222                         0,
 1223                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD0_ADDR,
 1224                         reg);
 1225 
 1226         /* Write 0 as MiscOption value to LEQ FSM */
 1227         al_serdes_25g_reg_write(
 1228                         obj,
 1229                         (enum al_serdes_reg_page)lane,
 1230                         0,
 1231                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD2_ADDR,
 1232                         0);
 1233 
 1234         /* Write the ArgumentValue to LEQ FSM if needed*/
 1235         if (opcode == AL_SERDES_25G_RX_LEQ_FSM_OPCODE_WRITE) {
 1236                 al_serdes_25g_reg_write(
 1237                                 obj,
 1238                                 (enum al_serdes_reg_page)lane,
 1239                                 0,
 1240                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CMD1_ADDR,
 1241                                 val);
 1242         }
 1243 
 1244         /* Issue an LEQ FSM Command Request */
 1245         al_serdes_25g_reg_masked_write(
 1246                         obj,
 1247                         (enum al_serdes_reg_page)lane,
 1248                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_ADDR,
 1249                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_MASK,
 1250                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_SHIFT,
 1251                         1);
 1252 
 1253         /* Poll on LEQ FSM Command acknowledge */
 1254         while (1) {
 1255                 al_serdes_25g_reg_masked_read(
 1256                                 obj,
 1257                                 (enum al_serdes_reg_page)lane,
 1258                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_ADDR,
 1259                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_LEQ_FSM_CMD_ACK_MASK,
 1260                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS5_LEQ_FSM_CMD_ACK_SHIFT,
 1261                                 &ack);
 1262 
 1263                 if (ack || (timeout == 0))
 1264                         break;
 1265 
 1266                 timeout--;
 1267                 al_udelay(1);
 1268         }
 1269 
 1270         if (ack) {
 1271                 uint8_t err1, err2;
 1272                 al_serdes_25g_reg_read(
 1273                                 obj,
 1274                                 (enum al_serdes_reg_page)lane,
 1275                                 0,
 1276                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_ADDR,
 1277                                 err);
 1278 
 1279                 err1 = (*err &
 1280                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR1_MASK) >>
 1281                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR1_SHIFT;
 1282                 err2 = (*err &
 1283                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR2_MASK) >>
 1284                         SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS0_LEQ_FSM_STATUS_ERROR2_SHIFT;
 1285 
 1286                 if (err1 || err2) {
 1287                         al_err("%s: error in RX LEQ FSM req, err status 1=0x%x, err status 2=0x%x",
 1288                                         __func__, err1, err2);
 1289                         status = -EIO;
 1290                 }
 1291 
 1292                 /* Read LEQ FSM Command return Value */
 1293                 al_serdes_25g_reg_read(
 1294                                 obj,
 1295                                 (enum al_serdes_reg_page)lane,
 1296                                 0,
 1297                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_STATUS3_ADDR,
 1298                                 data);
 1299 
 1300                 /* Clear an LEQ FSM Command Request */
 1301                 al_serdes_25g_reg_masked_write(
 1302                                 obj,
 1303                                 (enum al_serdes_reg_page)lane,
 1304                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_ADDR,
 1305                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_MASK,
 1306                                 SERDES_25G_LANE_LEQ_REFCLK_LEQ_FSM_CTRL0_LEQ_FSM_CMD_REQ_SHIFT,
 1307                                 0);
 1308         } else {
 1309                 al_err("%s: TO waiting for RX LEQ FSM req to complete (opcode %x, target %x, val %x)\n",
 1310                                 __func__, opcode, target, val);
 1311                 status = ETIMEDOUT;
 1312         }
 1313 
 1314         return status;
 1315 }
 1316 
 1317 /* enum values correspond to HW values, don't change! */
 1318 enum al_serdes_25g_tbus_obj {
 1319         AL_SERDES_25G_TBUS_OBJ_TOP      = 0,
 1320         AL_SERDES_25G_TBUS_OBJ_CMU      = 1,
 1321         AL_SERDES_25G_TBUS_OBJ_LANE     = 2,
 1322 };
 1323 
 1324 #define AL_SERDES_25G_TBUS_DELAY        1000 /* uSec */
 1325 #define AL_SERDES_25G_TBUS_ADDR_HIGH_SHIFT      5
 1326 
 1327 static int al_serdes_25g_tbus_read(
 1328                 struct al_serdes_grp_obj        *obj,
 1329                 enum al_serdes_lane     lane,
 1330                 enum al_serdes_25g_tbus_obj     tbus_obj,
 1331                 uint8_t offset,
 1332                 uint16_t        *data)
 1333 {
 1334         uint8_t addr_high, val_high, val_low;
 1335 
 1336         al_assert(lane < AL_SRDS_NUM_LANES);
 1337 
 1338         if (tbus_obj == AL_SERDES_25G_TBUS_OBJ_TOP)
 1339                 addr_high = AL_SERDES_25G_TBUS_OBJ_TOP;
 1340         else if (tbus_obj == AL_SERDES_25G_TBUS_OBJ_CMU)
 1341                 addr_high = AL_SERDES_25G_TBUS_OBJ_CMU;
 1342         else
 1343                 addr_high = AL_SERDES_25G_TBUS_OBJ_LANE + lane;
 1344 
 1345         addr_high <<= AL_SERDES_25G_TBUS_ADDR_HIGH_SHIFT;
 1346 
 1347         al_serdes_25g_reg_write(
 1348                         obj,
 1349                         AL_SRDS_REG_PAGE_TOP,
 1350                         0,
 1351                         SERDES_25G_TOP_TBUS_ADDR_7_0_ADDR,
 1352                         offset);
 1353 
 1354         al_serdes_25g_reg_write(
 1355                         obj,
 1356                         AL_SRDS_REG_PAGE_TOP,
 1357                         0,
 1358                         SERDES_25G_TOP_TBUS_ADDR_15_8_ADDR,
 1359                         addr_high);
 1360 
 1361         al_udelay(AL_SERDES_25G_TBUS_DELAY);
 1362 
 1363         al_serdes_25g_reg_read(
 1364                         obj,
 1365                         AL_SRDS_REG_PAGE_TOP,
 1366                         0,
 1367                         SERDES_25G_TOP_TBUS_DATA_7_0_ADDR,
 1368                         &val_low);
 1369 
 1370         al_serdes_25g_reg_masked_read(
 1371                         obj,
 1372                         AL_SRDS_REG_PAGE_TOP,
 1373                         SERDES_25G_TOP_TBUS_DATA_11_8_ADDR,
 1374                         SERDES_25G_TOP_TBUS_DATA_11_8_MASK,
 1375                         SERDES_25G_TOP_TBUS_DATA_11_8_SHIFT,
 1376                         &val_high);
 1377 
 1378         *data = (val_high << 8) | val_low;
 1379 
 1380         return 0;
 1381 }
 1382 
 1383 #define AL_SERDES_25G_RX_ADV_PARAMS_ATT_MASK    0x07
 1384 #define AL_SERDES_25G_RX_ADV_PARAMS_APG_MASK    0x03
 1385 #define AL_SERDES_25G_RX_ADV_PARAMS_LFG_MASK    0x1F
 1386 #define AL_SERDES_25G_RX_ADV_PARAMS_HFG_MASK    0x1F
 1387 #define AL_SERDES_25G_RX_ADV_PARAMS_MBG_MASK    0x0F
 1388 #define AL_SERDES_25G_RX_ADV_PARAMS_MBF_MASK    0x0F
 1389 #define AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_CNT                 8
 1390 #define AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_MASK                0x1F
 1391 #define AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_SIGN_SHIFT  7
 1392 
 1393 static void al_serdes_25g_rx_advanced_params_get(
 1394                 struct al_serdes_grp_obj        *obj,
 1395                 enum al_serdes_lane                     lane,
 1396                 void                                    *rx_params)
 1397 {
 1398         struct al_serdes_25g_adv_rx_params *params = rx_params;
 1399         uint8_t value, err;
 1400         int8_t tap_weight;
 1401         uint8_t tap_sign;
 1402         int8_t *tap_ptr_arr[AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_CNT];
 1403         int rc;
 1404         int i;
 1405 
 1406         rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ,
 1407                         AL_SERDES_25G_RX_LEQ_FSM_TARGET_PLE_ATT, 0, &value, &err);
 1408         if (rc || err) {
 1409                 al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read att, rc %d, err %d\n",
 1410                                 __func__, rc, err);
 1411                 return;
 1412         }
 1413         params->att = value & AL_SERDES_25G_RX_ADV_PARAMS_ATT_MASK;
 1414 
 1415         rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ,
 1416                         AL_SERDES_25G_RX_LEQ_FSM_TARGET_GN_APG, 0, &value, &err);
 1417         if (rc || err) {
 1418                 al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read apg, rc %d, err %d\n",
 1419                                 __func__, rc, err);
 1420                 return;
 1421         }
 1422         params->apg = value & AL_SERDES_25G_RX_ADV_PARAMS_APG_MASK;
 1423 
 1424         rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ,
 1425                         AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_LFG, 0, &value, &err);
 1426         if (rc || err) {
 1427                 al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read lfg, rc %d, err %d\n",
 1428                                 __func__, rc, err);
 1429                 return;
 1430         }
 1431         params->lfg = value & AL_SERDES_25G_RX_ADV_PARAMS_LFG_MASK;
 1432 
 1433         rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ,
 1434                         AL_SERDES_25G_RX_LEQ_FSM_TARGET_HFG_SQL, 0, &value, &err);
 1435         if (rc || err) {
 1436                 al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read hfg, rc %d, err %d\n",
 1437                                 __func__, rc, err);
 1438                 return;
 1439         }
 1440         params->hfg = value & AL_SERDES_25G_RX_ADV_PARAMS_HFG_MASK;
 1441 
 1442         rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ,
 1443                         AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBG, 0, &value, &err);
 1444         if (rc || err) {
 1445                 al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read mbg, rc %d, err %d\n",
 1446                                 __func__, rc, err);
 1447                 return;
 1448         }
 1449         params->mbg = value & AL_SERDES_25G_RX_ADV_PARAMS_MBG_MASK;
 1450 
 1451         rc = al_serdes_25g_rx_leq_fsm_op(obj, lane, AL_SERDES_25G_RX_LEQ_FSM_OPCODE_READ,
 1452                         AL_SERDES_25G_RX_LEQ_FSM_TARGET_EQ_MBF, 0, &value, &err);
 1453         if (rc || err) {
 1454                 al_err("%s: al_serdes_25g_rx_leq_fsm_op failed to read mbf, rc %d, err %d\n",
 1455                                 __func__, rc, err);
 1456                 return;
 1457         }
 1458         params->mbf = value & AL_SERDES_25G_RX_ADV_PARAMS_MBF_MASK;
 1459 
 1460         tap_ptr_arr[0] = &params->dfe_first_tap_even0_ctrl;
 1461         tap_ptr_arr[1] = &params->dfe_first_tap_even1_ctrl;
 1462         tap_ptr_arr[2] = &params->dfe_first_tap_odd0_ctrl;
 1463         tap_ptr_arr[3] = &params->dfe_first_tap_odd1_ctrl;
 1464         tap_ptr_arr[4] = &params->dfe_second_tap_ctrl;
 1465         tap_ptr_arr[5] = &params->dfe_third_tap_ctrl;
 1466         tap_ptr_arr[6] = &params->dfe_fourth_tap_ctrl;
 1467         tap_ptr_arr[7] = &params->dfe_fifth_tap_ctrl;
 1468 
 1469         for (i = 0; i < AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_CNT; i++) {
 1470                 al_serdes_25g_reg_read(
 1471                                 obj,
 1472                                 (enum al_serdes_reg_page)lane,
 1473                                 0,
 1474                                 SERDES_25G_LANE_DFE_REFCLK_TAP_VAL_STATUS0_ADDR + i,
 1475                                 &value);
 1476 
 1477                 tap_weight = value & AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_MASK;
 1478                 tap_sign = (value & AL_BIT(AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_SIGN_SHIFT)) >>
 1479                                 AL_SERDES_25G_RX_ADV_PARAMS_DFE_TAP_SIGN_SHIFT;
 1480                 if (tap_sign == 0)
 1481                         tap_weight = 0 - tap_weight;
 1482 
 1483                 *tap_ptr_arr[i] = tap_weight;
 1484         }
 1485 }
 1486 
 1487 #define AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_ADDR              0x0B
 1488 #define AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_MASK              0x3F
 1489 #define AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_SIGN_SHIFT        7
 1490 #define AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_ADDR             0x0C
 1491 #define AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_MASK             0xFFF
 1492 
 1493 static void al_serdes_25g_tx_diag_info_get(
 1494                 struct al_serdes_grp_obj        *obj,
 1495                 enum al_serdes_lane             lane,
 1496                 void *tx_info)
 1497 {
 1498         struct al_serdes_25g_tx_diag_info *info = tx_info;
 1499         uint8_t cal_x1, cal_x1_fixed, cal_x2, cal_xp5_fixed;
 1500         uint16_t val16, sign;
 1501         uint8_t val8, abs;
 1502         int rc;
 1503 
 1504         al_serdes_25g_reg_read(
 1505                         obj,
 1506                         (enum al_serdes_reg_page)lane,
 1507                         0,
 1508                         SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_ADDR,
 1509                         &val8);
 1510         info->regulated_supply = val8 & SERDES_25G_LANE_TOP_AFE_TXCP_CTRL0_REG_TXCP_TRIM_MASK;
 1511 
 1512         rc = al_serdes_25g_gcfsm2_read(
 1513                         obj,
 1514                         lane,
 1515                         AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_ADDR,
 1516                         &val16);
 1517         if (rc) {
 1518                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read dcd_trim, rc %d\n",
 1519                                 __func__, rc);
 1520                 return;
 1521         }
 1522 
 1523         abs = val16 & AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_MASK;
 1524         sign = (val16 & AL_BIT(AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_SIGN_SHIFT)) >>
 1525                         AL_SERDES_25G_TX_DIAG_GCFSM2_DCD_TRIM_SIGN_SHIFT;
 1526         if (sign)
 1527                 info->dcd_trim = abs;
 1528         else
 1529                 info->dcd_trim = 0 - abs;
 1530 
 1531         rc = al_serdes_25g_gcfsm2_read(
 1532                         obj,
 1533                         lane,
 1534                         AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_ADDR,
 1535                         &val16);
 1536         if (rc) {
 1537                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read clk_delay, rc %d\n",
 1538                                 __func__, rc);
 1539                 return;
 1540         }
 1541         info->clk_delay = val16 & AL_SERDES_25G_TX_DIAG_GCFSM2_CLK_DELAY_MASK;
 1542 
 1543         al_serdes_25g_reg_read(
 1544                         obj,
 1545                         (enum al_serdes_reg_page)lane,
 1546                         0,
 1547                         SERDES_25G_CM_TOP_AFE_TXTC_CTRL2_ADDR,
 1548                         &val8);
 1549         cal_x1 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_MASK) >>
 1550                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_SHIFT;
 1551         cal_x1_fixed = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_FIXED_MASK) >>
 1552                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL2_TXTC_CALP_X1_FIXED_SHIFT;
 1553         al_serdes_25g_reg_read(
 1554                         obj,
 1555                         (enum al_serdes_reg_page)lane,
 1556                         0,
 1557                         SERDES_25G_CM_TOP_AFE_TXTC_CTRL3_ADDR,
 1558                         &val8);
 1559         cal_x2 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_X2_MASK) >>
 1560                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_X2_SHIFT;
 1561         cal_xp5_fixed = (val8 &
 1562                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_XP5_FIXED_MASK) >>
 1563                                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL3_TXTC_CALP_XP5_FIXED_SHIFT;
 1564         info->calp_multiplied_by_2 = 4 * cal_x2 + 2 * cal_x1 + 2 * cal_x1_fixed + cal_xp5_fixed;
 1565 
 1566         al_serdes_25g_reg_read(
 1567                         obj,
 1568                         (enum al_serdes_reg_page)lane,
 1569                         0,
 1570                         SERDES_25G_CM_TOP_AFE_TXTC_CTRL0_ADDR,
 1571                         &val8);
 1572         cal_x1 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_MASK) >>
 1573                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_SHIFT;
 1574         cal_x1_fixed = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_FIXED_MASK) >>
 1575                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL0_TXTC_CALN_X1_FIXED_SHIFT;
 1576         al_serdes_25g_reg_read(
 1577                         obj,
 1578                         (enum al_serdes_reg_page)lane,
 1579                         0,
 1580                         SERDES_25G_CM_TOP_AFE_TXTC_CTRL1_ADDR,
 1581                         &val8);
 1582         cal_x2 = (val8 & SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_X2_MASK) >>
 1583                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_X2_SHIFT;
 1584         cal_xp5_fixed = (val8 &
 1585                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_XP5_FIXED_MASK) >>
 1586                                         SERDES_25G_CMU_TOP_AFE_TXTC_CTRL1_TXTC_CALN_XP5_FIXED_SHIFT;
 1587         info->caln_multiplied_by_2 = 4 * cal_x2 + 2 * cal_x1 + 2 * cal_x1_fixed + cal_xp5_fixed;
 1588 }
 1589 
 1590 #define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_ABS_MASK                      0x1F
 1591 #define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK                          0x3F
 1592 #define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_SIGN_SHIFT            5
 1593 #define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK                     0xFC0
 1594 #define AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT            6
 1595 #define AL_SERDES_25G_RX_DIAG_LEQ_EQ_COUNT                                      5
 1596 #define AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_EQ_ADDR                        0
 1597 #define AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_GAINSTAGE_ADDR         0x5
 1598 #define AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_EVEN_ADDR           0x6
 1599 #define AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_ODD_ADDR            0x7
 1600 #define AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_EVEN_ADDR            0x8
 1601 #define AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_ODD_ADDR                     0x9
 1602 #define AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_ADDR            0xF
 1603 #define AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_MASK            0xFFF
 1604 #define AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_EVEN_ADDR        0x11
 1605 #define AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_ODD_ADDR         0x12
 1606 #define AL_SERDES_25G_RX_DIAG_TBUS_EDGE_SLICER_ADDR                     0x13
 1607 #define AL_SERDES_25G_RX_DIAG_TBUS_EYE_SLICER_ADDR                      0x23
 1608 #define AL_SERDES_25G_RX_DIAG_TBUS_CDR_CLK_Q_ADDR                       0x2
 1609 #define AL_SERDES_25G_RX_DIAG_TBUS_CDR_CLK_I_ADDR                       0x1
 1610 #define AL_SERDES_25G_RX_DIAG_CDR_RXCLK_DLPF_L_ADDR                     0x26
 1611 #define AL_SERDES_25G_RX_DIAG_CDR_RXCLK_DLPF_H_ADDR                     0x27
 1612 
 1613 static inline void al_serdes_25g_rx_diag_5bit_signed_set(uint8_t packed_val, int8_t *ptr)
 1614 {
 1615         uint8_t abs, sign;
 1616 
 1617         abs = packed_val & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_ABS_MASK;
 1618         sign = (packed_val & AL_BIT(AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_SIGN_SHIFT)) >>
 1619                         AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_SIGN_SHIFT;
 1620         if (sign)
 1621                 *ptr = abs;
 1622         else
 1623                 *ptr = 0 - abs;
 1624 }
 1625 
 1626 static void al_serdes_25g_rx_diag_info_get(
 1627                 struct al_serdes_grp_obj        *obj,
 1628                 enum al_serdes_lane             lane,
 1629                 void *rx_info)
 1630 {
 1631         struct al_serdes_25g_rx_diag_info *info = rx_info;
 1632         uint16_t val16;
 1633         uint8_t val8, val8_2;
 1634         int rc;
 1635         int i;
 1636 
 1637         al_serdes_25g_reg_read(
 1638                         obj,
 1639                         (enum al_serdes_reg_page)lane,
 1640                         0,
 1641                         SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS0_ADDR,
 1642                         &val8);
 1643         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->los_offset);
 1644 
 1645         al_serdes_25g_reg_read(
 1646                         obj,
 1647                         (enum al_serdes_reg_page)lane,
 1648                         0,
 1649                         SERDES_25G_LANE_LOS_REFCLK_CALIBRATION_STATUS1_ADDR,
 1650                         &val8);
 1651         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->agc_offset);
 1652 
 1653         rc = al_serdes_25g_gcfsm2_read(
 1654                         obj,
 1655                         lane,
 1656                         AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_GAINSTAGE_ADDR,
 1657                         &val16);
 1658         if (rc) {
 1659                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read leq_gainstage, rc %d\n",
 1660                                 __func__, rc);
 1661                 return;
 1662         }
 1663         val8 = (uint8_t)val16;
 1664         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_gainstage_offset);
 1665 
 1666         for (i = 0; i < AL_SERDES_25G_RX_DIAG_LEQ_EQ_COUNT; i++) {
 1667                 rc = al_serdes_25g_gcfsm2_read(
 1668                                 obj,
 1669                                 lane,
 1670                                 AL_SERDES_25G_RX_DIAG_GCFSM2_LEQ_EQ_ADDR + i,
 1671                                 &val16);
 1672                 if (rc) {
 1673                         al_err("%s: al_serdes_25g_gcfsm2_read failed to read leq_eq %d, rc %d\n",
 1674                                         __func__, i, rc);
 1675                         return;
 1676                 }
 1677                 val8 = (uint8_t)val16;
 1678 
 1679                 switch (i) {
 1680                 case 0:
 1681                         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq1_offset);
 1682                         break;
 1683                 case 1:
 1684                         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq2_offset);
 1685                         break;
 1686                 case 2:
 1687                         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq3_offset);
 1688                         break;
 1689                 case 3:
 1690                         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq4_offset);
 1691                         break;
 1692                 case 4:
 1693                         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->leq_eq5_offset);
 1694                         break;
 1695                 default:
 1696                         break;
 1697                 }
 1698         }
 1699 
 1700         rc = al_serdes_25g_gcfsm2_read(
 1701                         obj,
 1702                         lane,
 1703                         AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_EVEN_ADDR,
 1704                         &val16);
 1705         if (rc) {
 1706                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read summer_even_offset, rc %d\n",
 1707                                 __func__, rc);
 1708                 return;
 1709         }
 1710         val8 = (uint8_t)val16;
 1711         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->summer_even_offset);
 1712 
 1713         rc = al_serdes_25g_gcfsm2_read(
 1714                         obj,
 1715                         lane,
 1716                         AL_SERDES_25G_RX_DIAG_GCFSM2_SUMMER_ODD_ADDR,
 1717                         &val16);
 1718         if (rc) {
 1719                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read summer_odd_offset, rc %d\n",
 1720                                 __func__, rc);
 1721                 return;
 1722         }
 1723         val8 = (uint8_t)val16;
 1724         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->summer_odd_offset);
 1725 
 1726         rc = al_serdes_25g_gcfsm2_read(
 1727                         obj,
 1728                         lane,
 1729                         AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_EVEN_ADDR,
 1730                         &val16);
 1731         if (rc) {
 1732                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read vscan_even_offset, rc %d\n",
 1733                                 __func__, rc);
 1734                 return;
 1735         }
 1736         val8 = (uint8_t)val16;
 1737         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->vscan_even_offset);
 1738 
 1739         rc = al_serdes_25g_gcfsm2_read(
 1740                         obj,
 1741                         lane,
 1742                         AL_SERDES_25G_RX_DIAG_GCFSM2_VSCAN_ODD_ADDR,
 1743                         &val16);
 1744         if (rc) {
 1745                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read vscan_odd_offset, rc %d\n",
 1746                                 __func__, rc);
 1747                 return;
 1748         }
 1749         val8 = (uint8_t)val16;
 1750         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->vscan_odd_offset);
 1751 
 1752         al_serdes_25g_tbus_read(
 1753                         obj,
 1754                         lane,
 1755                         AL_SERDES_25G_TBUS_OBJ_LANE,
 1756                         AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_EVEN_ADDR,
 1757                         &val16);
 1758         val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK);
 1759         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_even0_offset);
 1760         val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >>
 1761                         AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT);
 1762         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_even1_offset);
 1763 
 1764         al_serdes_25g_tbus_read(
 1765                         obj,
 1766                         lane,
 1767                         AL_SERDES_25G_TBUS_OBJ_LANE,
 1768                         AL_SERDES_25G_RX_DIAG_TBUS_DATA_SLICER_ODD_ADDR,
 1769                         &val16);
 1770         val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK);
 1771         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_odd0_offset);
 1772         val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >>
 1773                         AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT);
 1774         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->data_slicer_odd1_offset);
 1775 
 1776         al_serdes_25g_tbus_read(
 1777                         obj,
 1778                         lane,
 1779                         AL_SERDES_25G_TBUS_OBJ_LANE,
 1780                         AL_SERDES_25G_RX_DIAG_TBUS_EDGE_SLICER_ADDR,
 1781                         &val16);
 1782         val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK);
 1783         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->edge_slicer_even_offset);
 1784         val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >>
 1785                         AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT);
 1786         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->edge_slicer_odd_offset);
 1787 
 1788         al_serdes_25g_tbus_read(
 1789                         obj,
 1790                         lane,
 1791                         AL_SERDES_25G_TBUS_OBJ_LANE,
 1792                         AL_SERDES_25G_RX_DIAG_TBUS_EYE_SLICER_ADDR,
 1793                         &val16);
 1794         val8 = (uint8_t)(val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_MASK);
 1795         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->eye_slicer_even_offset);
 1796         val8 = (uint8_t)((val16 & AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_MASK) >>
 1797                         AL_SERDES_25G_RX_DIAG_SIGNED_5BIT_HIGH_SHIFT);
 1798         al_serdes_25g_rx_diag_5bit_signed_set(val8, &info->eye_slicer_odd_offset);
 1799 
 1800         al_serdes_25g_reg_masked_read(
 1801                         obj,
 1802                         (enum al_serdes_reg_page)lane,
 1803                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_ADDR,
 1804                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_RXCDR_HSCAN_CLKQ_MASK,
 1805                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL0_RXCDR_HSCAN_CLKQ_SHIFT,
 1806                         &info->cdr_clk_q);
 1807 
 1808         al_serdes_25g_reg_masked_read(
 1809                         obj,
 1810                         (enum al_serdes_reg_page)lane,
 1811                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_ADDR,
 1812                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_RXCDR_HSCAN_CLKI_MASK,
 1813                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL1_RXCDR_HSCAN_CLKI_SHIFT,
 1814                         &info->cdr_clk_i);
 1815 
 1816         al_serdes_25g_reg_masked_read(
 1817                         obj,
 1818                         (enum al_serdes_reg_page)lane,
 1819                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_ADDR,
 1820                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_RXCDR_HSCAN_EYE_MASK,
 1821                         SERDES_25G_LANE_CDR_REFCLK_AFE_PI_CTRL2_RXCDR_HSCAN_EYE_SHIFT,
 1822                         &info->cdr_dll);
 1823 
 1824         al_serdes_25g_reg_masked_read(
 1825                         obj,
 1826                         (enum al_serdes_reg_page)lane,
 1827                         SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_ADDR,
 1828                         SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_RXCDR_DOSC_MASK,
 1829                         SERDES_25G_LANE_CDR_REFCLK_AFE_VCO_CTRL2_RXCDR_DOSC_SHIFT,
 1830                         &info->cdr_vco_dosc);
 1831 
 1832         al_serdes_25g_reg_read(
 1833                         obj,
 1834                         (enum al_serdes_reg_page)lane,
 1835                         0,
 1836                         SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL1_ADDR,
 1837                         &val8_2);
 1838         al_serdes_25g_reg_read(
 1839                         obj,
 1840                         (enum al_serdes_reg_page)lane,
 1841                         0,
 1842                         SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL0_ADDR,
 1843                         &val8);
 1844         val8_2 &= SERDES_25G_LANE_CDR_RXCLK_LOAD_MODE_CTRL1_DLPF_VAL_8_MASK;
 1845         info->cdr_dlpf = (uint16_t)val8_2 << 8 | val8;
 1846 
 1847         rc = al_serdes_25g_gcfsm2_read(
 1848                         obj,
 1849                         lane,
 1850                         AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_ADDR,
 1851                         &val16);
 1852         if (rc) {
 1853                 al_err("%s: al_serdes_25g_gcfsm2_read failed to read cdr_vco_fr, rc %d\n",
 1854                                 __func__, rc);
 1855                 return;
 1856         }
 1857         info->cdr_vco_fr = val16 & AL_SERDES_25G_RX_DIAG_GCFSM2_CDR_VCO_FR_MASK;
 1858 
 1859         al_serdes_25g_reg_masked_read(
 1860                         obj,
 1861                         (enum al_serdes_reg_page)lane,
 1862                         SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_ADDR,
 1863                         SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_BLW_ZERO_MASK,
 1864                         SERDES_25G_LANE_LEQ_REFCLK_AFE_PLE_CTRL0_RXLEQ_PLE_BLW_ZERO_SHIFT,
 1865                         &info->ple_resistance);
 1866 
 1867         al_serdes_25g_reg_read(
 1868                         obj,
 1869                         (enum al_serdes_reg_page)lane,
 1870                         0,
 1871                         SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_ADDR,
 1872                         &val8);
 1873 
 1874         info->rx_term_mode = (val8 & SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_MASK) >>
 1875                         SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_HIZ_SHIFT;
 1876 
 1877         info->rx_coupling = (val8 & SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_MASK) >>
 1878                         SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL0_RXTERM_VCM_GND_SHIFT;
 1879 
 1880         al_serdes_25g_reg_masked_read(
 1881                         obj,
 1882                         (enum al_serdes_reg_page)lane,
 1883                         SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_ADDR,
 1884                         SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_MASK,
 1885                         SERDES_25G_LANE_TOP_AFE_RXTERM_CTRL1_RXTERM_VAL_SHIFT,
 1886                         &info->rx_term_cal_code);
 1887 
 1888         al_serdes_25g_reg_masked_read(
 1889                         obj,
 1890                         (enum al_serdes_reg_page)lane,
 1891                         SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_ADDR,
 1892                         SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_BIASI_TRIM_MASK,
 1893                         SERDES_25G_LANE_LEQ_REFCLK_AFE_BIAS_CTRL1_RXLEQ_BIASI_TRIM_SHIFT,
 1894                         &info->rx_sheet_res_cal_code);
 1895 }
 1896 
 1897 /******************************************************************************/
 1898 /******************************************************************************/
 1899 int al_serdes_25g_handle_init(
 1900         void __iomem                    *serdes_regs_base,
 1901         struct al_serdes_grp_obj        *obj)
 1902 {
 1903         al_dbg(
 1904                 "%s(%p, %p)\n",
 1905                 __func__,
 1906                 serdes_regs_base,
 1907                 obj);
 1908 
 1909         al_memset(obj, 0, sizeof(struct al_serdes_grp_obj));
 1910 
 1911         obj->regs_base = (struct al_serdes_regs *)serdes_regs_base;
 1912         obj->type_get = al_serdes_25g_type_get;
 1913         obj->reg_read = al_serdes_25g_reg_read;
 1914         obj->reg_write = al_serdes_25g_reg_write;
 1915         obj->bist_overrides_enable = NULL;
 1916         obj->bist_overrides_disable = NULL;
 1917         obj->rx_rate_change = NULL;
 1918         obj->group_pm_set = NULL;
 1919         obj->lane_pm_set = NULL;
 1920         obj->pma_hard_reset_group = NULL;
 1921         obj->pma_hard_reset_lane = NULL;
 1922         obj->loopback_control = NULL;
 1923         obj->bist_pattern_select = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_pattern_select);
 1924         obj->bist_tx_enable = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_tx_enable);
 1925         obj->bist_tx_err_inject = NULL;
 1926         obj->bist_rx_enable = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_rx_enable);
 1927         obj->bist_rx_status = AL_SRDS_ADV_SRVC(al_serdes_25g_bist_rx_status);
 1928         obj->tx_deemph_preset = NULL;
 1929         obj->tx_deemph_inc = NULL;
 1930         obj->tx_deemph_dec = NULL;
 1931         obj->eye_measure_run = NULL;
 1932         obj->eye_diag_sample = NULL;
 1933         obj->eye_diag_run = AL_SRDS_ADV_SRVC(al_serdes_25g_eye_diag_run);
 1934         obj->cdr_is_locked = AL_SRDS_ADV_SRVC(al_serdes_25g_cdr_is_locked);
 1935         obj->rx_valid = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_valid);
 1936         obj->signal_is_detected = AL_SRDS_ADV_SRVC(al_serdes_25g_signal_is_detected);
 1937         obj->tx_advanced_params_set = AL_SRDS_ADV_SRVC(al_serdes_25g_tx_advanced_params_set);
 1938         obj->tx_advanced_params_get = AL_SRDS_ADV_SRVC(al_serdes_25g_tx_advanced_params_get);
 1939         obj->rx_advanced_params_set = NULL;
 1940         obj->rx_advanced_params_get = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_advanced_params_get);
 1941         obj->tx_diag_info_get = AL_SRDS_ADV_SRVC(al_serdes_25g_tx_diag_info_get);
 1942         obj->rx_diag_info_get = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_diag_info_get);
 1943         obj->mode_set_sgmii = NULL;
 1944         obj->mode_set_kr = NULL;
 1945         obj->rx_equalization = AL_SRDS_ADV_SRVC(al_serdes_25g_rx_equalization);
 1946         obj->calc_eye_size = AL_SRDS_ADV_SRVC(al_serdes_25g_calc_eye_size);
 1947         obj->sris_config = NULL;
 1948 
 1949         return 0;
 1950 }
 1951 

Cache object: ab231e20dad4118c063ac8d38f7d0b82


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.