[U-Boot] [PATCH v7] net/phy: Add support for CS4315/CS4340 PHY

Joe Hershberger joe.hershberger at gmail.com
Tue Nov 25 23:33:39 CET 2014


On Mon, Nov 10, 2014 at 4:32 AM, Shengzhou Liu <Shengzhou.Liu at freescale.com>
wrote:
>
> Add support for Cortina CS4315/CS4340 10G PHY.
> - This driver loads CS43xx firmware from NOR/NAND/SPI/SD device
>   to initialize Cortina PHY.
> - Cortina PHY has non-standard offset of PHY ID registers, thus
>   we define own get_phy_id() to override default get_phy_id().
> - To define macro CONFIG_PHY_CORTINA will enable this driver.
>
> Signed-off-by: Shengzhou Liu <Shengzhou.Liu at freescale.com>
> ---
> v7: reorder it in alphabetical order in Makefile
> v6: polish it in phy.c and phy.h in alphabetical order
> v5: fix unclaimed variable in case of nand boot.
> v4: add support for loading cortina phy ucode from NAND/SPI/SD
> v3: move devad as '0' in cortina.c instead of in phy.c
> v2: no change.
>
>  drivers/net/phy/Makefile  |   1 +
>  drivers/net/phy/cortina.c | 333
++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/net/phy/phy.c     |   3 +
>  include/cortina.h         |  75 +++++++++++
>  include/phy.h             |   2 +
>  5 files changed, 414 insertions(+)
>  create mode 100644 drivers/net/phy/cortina.c
>  create mode 100644 include/cortina.h
>
> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
> index 9556536..f46bf00 100644
> --- a/drivers/net/phy/Makefile
> +++ b/drivers/net/phy/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_PHYLIB) += phy.o
>  obj-$(CONFIG_PHYLIB_10G) += generic_10g.o
>  obj-$(CONFIG_PHY_ATHEROS) += atheros.o
>  obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
> +obj-$(CONFIG_PHY_CORTINA) += cortina.o
>  obj-$(CONFIG_PHY_DAVICOM) += davicom.o
>  obj-$(CONFIG_PHY_ET1011C) += et1011c.o
>  obj-$(CONFIG_PHY_LXT) += lxt.o
> diff --git a/drivers/net/phy/cortina.c b/drivers/net/phy/cortina.c
> new file mode 100644
> index 0000000..254f056
> --- /dev/null
> +++ b/drivers/net/phy/cortina.c
> @@ -0,0 +1,333 @@
> +/*
> + * Cortina CS4315/CS4340 10G PHY drivers
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + *
> + * Copyright 2014 Freescale Semiconductor, Inc.
> + *
> + */
> +
> +#include <config.h>
> +#include <common.h>
> +#include <malloc.h>
> +#include <linux/ctype.h>
> +#include <linux/string.h>
> +#include <linux/err.h>
> +#include <phy.h>
> +#include <cortina.h>
> +#ifdef CONFIG_SYS_CORTINA_FW_IN_NAND
> +#include <nand.h>
> +#elif defined(CONFIG_SYS_CORTINA_FW_IN_SPIFLASH)
> +#include <spi_flash.h>
> +#elif defined(CONFIG_SYS_CORTINA_FW_IN_MMC)
> +#include <mmc.h>
> +#endif
> +
> +#ifndef CONFIG_PHYLIB_10G
> +#error The Cortina PHY needs 10G support
> +#endif
> +
> +struct cortina_reg_config cortina_reg_cfg[] = {
> +       /* CS4315_enable_sr_mode */
> +       {VILLA_GLOBAL_MSEQCLKCTRL, 0x8004},
> +       {VILLA_MSEQ_OPTIONS, 0xf},
> +       {VILLA_MSEQ_PC, 0x0},
> +       {VILLA_MSEQ_BANKSELECT,    0x4},
> +       {VILLA_LINE_SDS_COMMON_SRX0_RX_CPA, 0x55},
> +       {VILLA_LINE_SDS_COMMON_SRX0_RX_LOOP_FILTER, 0x30},
> +       {VILLA_DSP_SDS_SERDES_SRX_DFE0_SELECT, 0x1},
> +       {VILLA_DSP_SDS_DSP_COEF_DFE0_SELECT, 0x2},
> +       {VILLA_LINE_SDS_COMMON_SRX0_RX_CPB, 0x2003},
> +       {VILLA_DSP_SDS_SERDES_SRX_FFE_DELAY_CTRL, 0xF047},
> +       {VILLA_MSEQ_ENABLE_MSB, 0x0000},
> +       {VILLA_MSEQ_SPARE21_LSB, 0x6},
> +       {VILLA_MSEQ_RESET_COUNT_LSB, 0x0},
> +       {VILLA_MSEQ_SPARE12_MSB, 0x0000},
> +       /*
> +        * to invert the receiver path, uncomment the next line
> +        * write (VILLA_MSEQ_SPARE12_MSB, 0x4000)
> +        *
> +        * SPARE2_LSB is used to configure the device while in sr mode to
> +        * enable power savings and to use the optical module LOS signal.
> +        * in power savings mode, the internal prbs checker can not be
used.
> +        * if the optical module LOS signal is used as an input to the
micro
> +        * code, then the micro code will wait until the optical module
> +        * LOS = 0 before turning on the adaptive equalizer.
> +        * Setting SPARE2_LSB bit 0 to 1 places the devie in power
savings mode
> +        * while setting bit 0 to 0 disables power savings mode.
> +        * Setting SPARE2_LSB bit 2 to 0 configures the device to use the
> +        * optical module LOS signal while setting bit 2 to 1 configures
the
> +        * device so that it will ignore the optical module LOS
SPARE2_LSB = 0
> +        */
> +
> +       /* enable power savings, ignore optical module LOS */
> +       {VILLA_MSEQ_SPARE2_LSB, 0x5},
> +
> +       {VILLA_MSEQ_SPARE7_LSB, 0x1e},
> +       {VILLA_MSEQ_BANKSELECT, 0x4},
> +       {VILLA_MSEQ_SPARE9_LSB, 0x2},
> +       {VILLA_MSEQ_SPARE3_LSB, 0x0F53},
> +       {VILLA_MSEQ_SPARE3_MSB, 0x2006},
> +       {VILLA_MSEQ_SPARE8_LSB, 0x3FF7},
> +       {VILLA_MSEQ_SPARE8_MSB, 0x0A46},
> +       {VILLA_MSEQ_COEF8_FFE0_LSB, 0xD500},
> +       {VILLA_MSEQ_COEF8_FFE1_LSB, 0x0200},
> +       {VILLA_MSEQ_COEF8_FFE2_LSB, 0xBA00},
> +       {VILLA_MSEQ_COEF8_FFE3_LSB, 0x0100},
> +       {VILLA_MSEQ_COEF8_FFE4_LSB, 0x0300},
> +       {VILLA_MSEQ_COEF8_FFE5_LSB, 0x0300},
> +       {VILLA_MSEQ_COEF8_DFE0_LSB, 0x0700},
> +       {VILLA_MSEQ_COEF8_DFE0N_LSB, 0x0E00},
> +       {VILLA_MSEQ_COEF8_DFE1_LSB, 0x0B00},
> +       {VILLA_DSP_SDS_DSP_COEF_LARGE_LEAK, 0x2},
> +       {VILLA_DSP_SDS_SERDES_SRX_DAC_ENABLEB_LSB, 0xD000},
> +       {VILLA_MSEQ_POWER_DOWN_LSB, 0xFFFF},
> +       {VILLA_MSEQ_POWER_DOWN_MSB, 0x0},
> +       {VILLA_MSEQ_CAL_RX_SLICER, 0x80},
> +       {VILLA_DSP_SDS_SERDES_SRX_DAC_BIAS_SELECT1_MSB, 0x3f},
> +       {VILLA_GLOBAL_MSEQCLKCTRL, 0x4},
> +       {VILLA_MSEQ_OPTIONS, 0x7},
> +
> +       /* set up min value for ffe1 */
> +       {VILLA_MSEQ_COEF_INIT_SEL, 0x2},
> +       {VILLA_DSP_SDS_DSP_PRECODEDINITFFE21, 0x41},
> +
> +       /* CS4315_sr_rx_pre_eq_set_4in */
> +       {VILLA_GLOBAL_MSEQCLKCTRL, 0x8004},
> +       {VILLA_MSEQ_OPTIONS, 0xf},
> +       {VILLA_MSEQ_BANKSELECT, 0x4},
> +       {VILLA_MSEQ_PC, 0x0},
> +
> +       /* for lengths from 3.5 to 4.5inches */
> +       {VILLA_MSEQ_SERDES_PARAM_LSB, 0x0306},
> +       {VILLA_MSEQ_SPARE25_LSB, 0x0306},
> +       {VILLA_MSEQ_SPARE21_LSB, 0x2},
> +       {VILLA_MSEQ_SPARE23_LSB, 0x2},
> +       {VILLA_MSEQ_CAL_RX_DFE_EQ, 0x0},
> +
> +       {VILLA_GLOBAL_MSEQCLKCTRL, 0x4},
> +       {VILLA_MSEQ_OPTIONS, 0x7},
> +
> +       /* CS4315_rx_drive_4inch */
> +       /* for length  4inches */
> +       {VILLA_GLOBAL_VILLA2_COMPATIBLE, 0x0000},
> +       {VILLA_HOST_SDS_COMMON_STX0_TX_OUTPUT_CTRLA, 0x3023},
> +       {VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLB, 0xc01E},
> +
> +       /* CS4315_tx_drive_4inch */
> +       /* for length  4inches */
> +       {VILLA_GLOBAL_VILLA2_COMPATIBLE, 0x0000},
> +       {VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLA, 0x3023},
> +       {VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLB, 0xc01E},
> +};
> +
> +void cs4340_upload_firmware(struct phy_device *phydev)
> +{
> +       char line_temp[0x50] = {0};
> +       char reg_addr[0x50] = {0};
> +       char reg_data[0x50] = {0};
> +       int i, line_cnt = 0, column_cnt = 0;
> +       struct cortina_reg_config fw_temp;
> +       char *addr = NULL;
> +
> +#if defined(CONFIG_SYS_CORTINA_FW_IN_NOR) || \
> +       defined(CONFIG_SYS_CORTINA_FW_IN_REMOTE)
> +
> +       addr = (char *)CONFIG_CORTINA_FW_ADDR;
> +#elif defined(CONFIG_SYS_CORTINA_FW_IN_NAND)
> +       int ret;
> +       size_t fw_length = CONFIG_CORTINA_FW_LENGTH;
> +
> +       addr = malloc(CONFIG_CORTINA_FW_LENGTH);
> +       ret = nand_read(&nand_info[0], (loff_t)CONFIG_CORTINA_FW_ADDR,
> +                      &fw_length, (u_char *)addr);
> +       if (ret == -EUCLEAN) {
> +               printf("NAND read of Cortina firmware at 0x%x failed
%d\n",
> +                      CONFIG_CORTINA_FW_ADDR, ret);
> +       }
> +#elif defined(CONFIG_SYS_CORTINA_FW_IN_SPIFLASH)
> +       int ret;
> +       struct spi_flash *ucode_flash;
> +
> +       addr = malloc(CONFIG_CORTINA_FW_LENGTH);
> +       ucode_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
CONFIG_ENV_SPI_CS,
> +                               CONFIG_ENV_SPI_MAX_HZ,
CONFIG_ENV_SPI_MODE);
> +       if (!ucode_flash) {
> +               puts("SF: probe for Cortina ucode failed\n");
> +       } else {
> +               ret = spi_flash_read(ucode_flash, CONFIG_CORTINA_FW_ADDR,
> +                                    CONFIG_CORTINA_FW_LENGTH, addr);
> +               if (ret)
> +                       puts("SF: read for Cortina ucode failed\n");
> +               spi_flash_free(ucode_flash);
> +       }
> +#elif defined(CONFIG_SYS_CORTINA_FW_IN_MMC)
> +       int dev = CONFIG_SYS_MMC_ENV_DEV;
> +       u32 cnt = CONFIG_CORTINA_FW_LENGTH / 512;
> +       u32 blk = CONFIG_CORTINA_FW_ADDR / 512;
> +       struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
> +
> +       if (!mmc) {
> +               puts("Failed to find MMC device for Cortina ucode\n");
> +       } else {
> +               addr = malloc(CONFIG_CORTINA_FW_LENGTH);
> +               printf("MMC read: dev # %u, block # %u, count %u ...\n",
> +                      dev, blk, cnt);
> +               mmc_init(mmc);
> +               (void)mmc->block_dev.block_read(dev, blk, cnt, addr);
> +               /* flush cache after read */
> +               flush_cache((ulong)addr, cnt * 512);
> +       }
> +#endif
> +
> +       while (*addr != 'Q') {
> +               i = 0;
> +
> +               while (*addr != 0x0a) {
> +                       line_temp[i++] = *addr++;
> +                       if (0x50 < i) {
> +                               printf("Not found Cortina PHY ucode at
0x%x\n",
> +                                      CONFIG_CORTINA_FW_ADDR);
> +                               return;
> +                       }
> +               }
> +
> +               addr++;  /* skip '\n' */
> +               line_cnt++;
> +               column_cnt = i;
> +               line_temp[column_cnt] = '\0';
> +
> +               if (CONFIG_CORTINA_FW_LENGTH < line_cnt)
> +                       return;
> +
> +               for (i = 0; i < column_cnt; i++) {
> +                       if (isspace(line_temp[i++]))
> +                               break;
> +               }
> +
> +               memcpy(reg_addr, line_temp, i);
> +               memcpy(reg_data, &line_temp[i], column_cnt - i);
> +               strim(reg_addr);
> +               strim(reg_data);
> +               fw_temp.reg_addr = (simple_strtoul(reg_addr, NULL, 0)) &
0xffff;
> +               fw_temp.reg_value = (simple_strtoul(reg_data, NULL, 0)) &
> +                                    0xffff;
> +               phy_write(phydev, 0x00, fw_temp.reg_addr,
fw_temp.reg_value);
> +       }
> +}
> +
> +int cs4340_phy_init(struct phy_device *phydev)
> +{
> +       int timeout = 100;  /* 100ms */
> +       int reg_value;
> +
> +       /* step1: BIST test */
> +       phy_write(phydev, 0x00, VILLA_GLOBAL_MSEQCLKCTRL,     0x0004);
> +       phy_write(phydev, 0x00, VILLA_GLOBAL_LINE_SOFT_RESET, 0x0000);
> +       phy_write(phydev, 0x00, VILLA_GLOBAL_BIST_CONTROL,    0x0001);
> +       while (--timeout) {
> +               reg_value = phy_read(phydev, 0x00,
VILLA_GLOBAL_BIST_STATUS);
> +               if (reg_value & mseq_edc_bist_done) {
> +                       if (0 == (reg_value & mseq_edc_bist_fail))
> +                               break;
> +               }
> +               udelay(1000);
> +       }
> +
> +       if (!timeout) {
> +               printf("%s BIST mseq_edc_bist_done timeout!\n", __func__);
> +               return -1;
> +       }
> +
> +       /* setp2: upload ucode */

Misspelling:  step2

>
> +       cs4340_upload_firmware(phydev);
> +       reg_value = phy_read(phydev, 0x00,
VILLA_GLOBAL_DWNLD_CHECKSUM_STATUS);
> +       if (reg_value) {
> +               debug("%s checksum status failed.\n", __func__);
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +int cs4340_config(struct phy_device *phydev)
> +{
> +       cs4340_phy_init(phydev);
> +       return 0;
> +}
> +
> +int cs4340_startup(struct phy_device *phydev)
> +{
> +       phydev->link = 1;
> +
> +       /* For now just lie and say it's 10G all the time */
> +       phydev->speed = SPEED_10000;
> +       phydev->duplex = DUPLEX_FULL;
> +       return 0;
> +}
> +
> +struct phy_driver cs4340_driver = {
> +       .name = "Cortina CS4315/CS4340",
> +       .uid = PHY_UID_CS4340,
> +       .mask = 0xfffffff0,
> +       .features = PHY_10G_FEATURES,
> +       .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
> +                MDIO_DEVS_PHYXS | MDIO_DEVS_AN |
> +                MDIO_DEVS_VEND1 | MDIO_DEVS_VEND2),
> +       .config = &cs4340_config,
> +       .startup = &cs4340_startup,
> +       .shutdown = &gen10g_shutdown,
> +};
> +
> +int phy_cortina_init(void)
> +{
> +       phy_register(&cs4340_driver);
> +       return 0;
> +}
> +
> +int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
> +{
> +       int phy_reg;
> +       bool is_cortina_phy = false;
> +
> +       switch (addr) {
> +#ifdef CORTINA_PHY_ADDR1
> +       case CORTINA_PHY_ADDR1:

Is this supposed to be set by the user?  If so it should be
CONFIG_CORTINA_PHY_ADDR1
Same goes for the other 3 below.

> +#endif
> +#ifdef CORTINA_PHY_ADDR2
> +       case CORTINA_PHY_ADDR2:
> +#endif
> +#ifdef CORTINA_PHY_ADDR3
> +       case CORTINA_PHY_ADDR3:
> +#endif
> +#ifdef CORTINA_PHY_ADDR4
> +       case CORTINA_PHY_ADDR4:
> +#endif

It is peculiar to have this code here in the case that none of
CONFIG_CORTINA_PHY_ADDR* are defined.  Perhaps you should have a
pre-compiler test to ensure at least one is defined.

> +               is_cortina_phy = true;
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       /* Cortina PHY has non-standard offset of PHY ID registers */

I don't quite understand this comment and the code that follows.  I thought
this whole driver was just for the cortina phy.  Why do you have code for
handling some other case in here?  Maybe I'mm just being confused by
unclear variable names.

> +       if (is_cortina_phy)
> +               phy_reg = bus->read(bus, addr, 0,
VILLA_GLOBAL_CHIP_ID_LSB);
> +       else
> +               phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
> +
> +       if (phy_reg < 0)
> +               return -EIO;
> +
> +       *phy_id = (phy_reg & 0xffff) << 16;
> +       if (is_cortina_phy)
> +               phy_reg = bus->read(bus, addr, 0,
VILLA_GLOBAL_CHIP_ID_MSB);
> +       else
> +               phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
> +
> +       if (phy_reg < 0)
> +               return -EIO;
> +
> +       *phy_id |= (phy_reg & 0xffff);
> +
> +       return 0;
> +}
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 1d6c14f..1782159 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -448,6 +448,9 @@ int phy_init(void)
>  #ifdef CONFIG_PHY_BROADCOM
>         phy_broadcom_init();
>  #endif
> +#ifdef CONFIG_PHY_CORTINA
> +       phy_cortina_init();
> +#endif
>  #ifdef CONFIG_PHY_DAVICOM
>         phy_davicom_init();
>  #endif
> diff --git a/include/cortina.h b/include/cortina.h
> new file mode 100644
> index 0000000..6cadd28
> --- /dev/null
> +++ b/include/cortina.h
> @@ -0,0 +1,75 @@
> +/*
> + * Cortina PHY drivers
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + *
> + * Copyright 2014 Freescale Semiconductor, Inc.
> + */
> +
> +#ifndef _CORTINA_H_
> +#define _CORTINA_H_
> +
> +#define VILLA_GLOBAL_CHIP_ID_LSB     0x000
> +#define VILLA_GLOBAL_CHIP_ID_MSB     0x001
> +#define VILLA_GLOBAL_BIST_CONTROL    0x002
> +#define VILLA_GLOBAL_BIST_STATUS     0x003
> +#define VILLA_GLOBAL_LINE_SOFT_RESET 0x007
> +#define VILLA_GLOBAL_HOST_SOFT_RESET 0x008
> +#define VILLA_GLOBAL_DWNLD_CHECKSUM_CTRL 0x00A
> +#define VILLA_GLOBAL_DWNLD_CHECKSUM_STATUS 0x00B
> +#define VILLA_GLOBAL_MSEQCLKCTRL 0x00E
> +#define VILLA_MSEQ_OPTIONS       0x1D0
> +#define VILLA_MSEQ_PC           0x1D3
> +#define VILLA_MSEQ_BANKSELECT    0x1DF
> +#define VILLA_DSP_SDS_DSP_COEF_DFE0_SELECT     0x2DB
> +#define VILLA_DSP_SDS_SERDES_SRX_DFE0_SELECT   0x36E
> +#define VILLA_LINE_SDS_COMMON_SRX0_RX_LOOP_FILTER   0x403
> +#define VILLA_LINE_SDS_COMMON_SRX0_RX_CPA      0x404
> +#define VILLA_LINE_SDS_COMMON_SRX0_RX_CPB      0x405
> +#define VILLA_DSP_SDS_SERDES_SRX_FFE_DELAY_CTRL        0x369
> +#define VILLA_MSEQ_ENABLE_MSB  0x194
> +#define VILLA_MSEQ_SPARE21_LSB 0x226
> +#define VILLA_MSEQ_RESET_COUNT_LSB  0x1E0
> +#define VILLA_MSEQ_SPARE12_MSB  0x215
> +#define VILLA_MSEQ_SPARE2_LSB   0x200
> +#define VILLA_MSEQ_SPARE7_LSB   0x20A
> +#define VILLA_MSEQ_SPARE9_LSB   0x20E
> +#define VILLA_MSEQ_SPARE3_LSB   0x202
> +#define VILLA_MSEQ_SPARE3_MSB   0x203
> +#define VILLA_MSEQ_SPARE8_LSB   0x20C
> +#define VILLA_MSEQ_SPARE8_MSB   0x20D
> +#define VILLA_MSEQ_COEF8_FFE0_LSB 0x1E2
> +#define VILLA_MSEQ_COEF8_FFE1_LSB 0x1E4
> +#define VILLA_MSEQ_COEF8_FFE2_LSB 0x1E6
> +#define VILLA_MSEQ_COEF8_FFE3_LSB 0x1E8
> +#define VILLA_MSEQ_COEF8_FFE4_LSB 0x1EA
> +#define VILLA_MSEQ_COEF8_FFE5_LSB 0x1EC
> +#define VILLA_MSEQ_COEF8_DFE0_LSB 0x1F0
> +#define VILLA_MSEQ_COEF8_DFE0N_LSB 0x1EE
> +#define VILLA_MSEQ_COEF8_DFE1_LSB  0x1F2
> +#define VILLA_DSP_SDS_DSP_COEF_LARGE_LEAK 0x2E2
> +#define VILLA_DSP_SDS_SERDES_SRX_DAC_ENABLEB_LSB 0x360
> +#define VILLA_MSEQ_POWER_DOWN_LSB  0x198
> +#define VILLA_MSEQ_POWER_DOWN_MSB  0x199
> +#define VILLA_MSEQ_CAL_RX_SLICER   0x1B8
> +#define VILLA_DSP_SDS_SERDES_SRX_DAC_BIAS_SELECT1_MSB 0x365
> +#define VILLA_MSEQ_COEF_INIT_SEL  0x1AE
> +#define VILLA_DSP_SDS_DSP_PRECODEDINITFFE21 0x26A
> +#define VILLA_MSEQ_SERDES_PARAM_LSB 0x195
> +#define VILLA_MSEQ_SPARE25_LSB 0x22E
> +#define VILLA_MSEQ_SPARE23_LSB 0x22A
> +#define VILLA_MSEQ_CAL_RX_DFE_EQ 0x1BA
> +#define VILLA_GLOBAL_VILLA2_COMPATIBLE      0x030
> +#define VILLA_HOST_SDS_COMMON_STX0_TX_OUTPUT_CTRLA  0x812
> +#define VILLA_HOST_SDS_COMMON_STX0_TX_OUTPUT_CTRLB  0x813
> +#define VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLA 0x427
> +#define VILLA_LINE_SDS_COMMON_STX0_TX_OUTPUT_CTRLB 0x428
> +
> +#define mseq_edc_bist_done (0x1<<0)
> +#define mseq_edc_bist_fail (0x1<<8)
> +
> +struct cortina_reg_config {
> +       unsigned short reg_addr;
> +       unsigned short reg_value;
> +};
> +#endif
> diff --git a/include/phy.h b/include/phy.h
> index 5eafe6b..0520435 100644
> --- a/include/phy.h
> +++ b/include/phy.h
> @@ -225,6 +225,7 @@ int gen10g_discover_mmds(struct phy_device *phydev);
>
>  int phy_atheros_init(void);
>  int phy_broadcom_init(void);
> +int phy_cortina_init(void);
>  int phy_davicom_init(void);
>  int phy_et1011c_init(void);
>  int phy_lxt_init(void);
> @@ -239,6 +240,7 @@ int phy_vitesse_init(void);
>  int board_phy_config(struct phy_device *phydev);
>
>  /* PHY UIDs for various PHYs that are referenced in external code */
> +#define PHY_UID_CS4340  0x13e51002
>  #define PHY_UID_TN2020 0x00a19410
>
>  #endif
> --
> 1.8.0
>


More information about the U-Boot mailing list