diff options
author | David Hendricks <dhendricks@fb.com> | 2018-03-09 14:30:38 -0800 |
---|---|---|
committer | Philipp Deppenwiese <zaolin.daisuki@gmail.com> | 2018-07-03 15:53:32 +0000 |
commit | 7d48ac5c7dfb52fc470bbad1013b4d460bc6a1e0 (patch) | |
tree | 42002ba1e86627339ff4a6cf38efb4b3f00033bb /src/vendorcode/cavium/bdk/libbdk-hal/if/bdk-if-phy-vetesse-8514.c | |
parent | d837e660074e0621d63f59515f933c209441b653 (diff) | |
download | coreboot-7d48ac5c7dfb52fc470bbad1013b4d460bc6a1e0.tar.xz |
soc/cavium: Integrate BDK files into coreboot
* Make it compile.
* Fix whitespace errors.
* Fix printf formats.
* Add missing headers includes
* Guard headers with ifdefs
Compile DRAM init code in romstage.
Compile QLM, PCIe, RNG, PHY, GPIO, MDIO init code in ramstage.
Change-Id: I0a93219a14bfb6ebe41103a825d5032b11e7f2c6
Signed-off-by: David Hendricks <dhendricks@fb.com>
Reviewed-on: https://review.coreboot.org/25089
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/vendorcode/cavium/bdk/libbdk-hal/if/bdk-if-phy-vetesse-8514.c')
-rw-r--r-- | src/vendorcode/cavium/bdk/libbdk-hal/if/bdk-if-phy-vetesse-8514.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/vendorcode/cavium/bdk/libbdk-hal/if/bdk-if-phy-vetesse-8514.c b/src/vendorcode/cavium/bdk/libbdk-hal/if/bdk-if-phy-vetesse-8514.c new file mode 100644 index 0000000000..4d6ef8d25d --- /dev/null +++ b/src/vendorcode/cavium/bdk/libbdk-hal/if/bdk-if-phy-vetesse-8514.c @@ -0,0 +1,224 @@ +/***********************license start*********************************** +* Copyright (c) 2003-2016 Cavium Inc. (support@cavium.com). All rights +* reserved. +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* +* * Neither the name of Cavium Inc. nor the names of +* its contributors may be used to endorse or promote products +* derived from this software without specific prior written +* permission. +* +* This Software, including technical data, may be subject to U.S. export +* control laws, including the U.S. Export Administration Act and its +* associated regulations, and may be subject to export or import +* regulations in other countries. +* +* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" +* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR +* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT +* TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY +* REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT +* DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES +* OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR +* PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, +* QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK +* ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. +***********************license end**************************************/ +#include <bdk.h> +#include <libbdk-hal/if/bdk-if.h> +#include <libbdk-hal/bdk-mdio.h> +#include <libbdk-hal/bdk-qlm.h> + +#define VSC_PHY_STD_PAGE (0x0) +#define VSC_PHY_EXT1_PAGE (0x1) +#define VSC_PHY_EXT2_PAGE (0x2) +#define VSC_PHY_EXT3_PAGE (0x3) +#define VSC_PHY_EXT4_PAGE (0x4) +#define VSC_PHY_GPIO_PAGE (0x10) +#define VSC_PHY_TEST_PAGE (0x2A30) +#define VSC_PHY_TR_PAGE (0x52B5) + +const uint16_t init_script_rev_a[] = { +// Op, Page, Reg, Value, Mask +// 0, 1, 2, 3, 4 +// --, ------, ----, ------, ----- + 0, 0x0000, 0x1f, 0x0000, 0xffff, + 1, 0x0000, 0x16, 0x0001, 0x0001, + 0, 0x0001, 0x1f, 0x2A30, 0xffff, + 1, 0x2A30, 0x08, 0x8000, 0x8000, + 0, 0x2A30, 0x1f, 0x52B5, 0xffff, + 0, 0x52B5, 0x12, 0x0068, 0xffff, + 0, 0x52B5, 0x11, 0x8980, 0xffff, + 0, 0x52B5, 0x10, 0x8f90, 0xffff, + 0, 0x52B5, 0x12, 0x0000, 0xffff, + 0, 0x52B5, 0x11, 0x0003, 0xffff, + 0, 0x52B5, 0x10, 0x8796, 0xffff, + 0, 0x52B5, 0x12, 0x0050, 0xffff, + 0, 0x52B5, 0x11, 0x100f, 0xffff, + 0, 0x52B5, 0x10, 0x87fa, 0xffff, + 0, 0x52B5, 0x1f, 0x2A30, 0xffff, + 1, 0x2A30, 0x08, 0x0000, 0x8000, + 0, 0x2A30, 0x1f, 0x0000, 0xffff, + 1, 0x0000, 0x16, 0x0000, 0x0001, + 0xf, 0xffff, 0xff, 0xffff, 0xffff +}; + +static void wr_masked(bdk_node_t node, int mdio_bus, int phy_addr, int reg, int value, int mask) +{ + int nmask = ~mask; + int old = bdk_mdio_read(node, mdio_bus, phy_addr, reg); + int vmask = value & mask; + int newv = old & nmask; + newv = newv | vmask; + bdk_mdio_write(node, mdio_bus, phy_addr, reg, newv); +} +static void vitesse_init_script(bdk_node_t node, int mdio_bus, int phy_addr) +{ + const uint16_t *ptr; + uint16_t reg_addr; + uint16_t reg_val; + uint16_t mask; + + BDK_TRACE(PHY,"In %s\n",__FUNCTION__); + BDK_TRACE(PHY,"Loading init script for VSC8514\n"); + + ptr = init_script_rev_a; + while (*ptr != 0xf) + { + reg_addr = *(ptr+2); + reg_val = *(ptr+3); + mask = *(ptr+4); + ptr+=5; + if (mask != 0xffff) + { + wr_masked(node, mdio_bus, phy_addr, reg_addr,reg_val,mask); + } + else + { + bdk_mdio_write(node,mdio_bus,phy_addr,reg_addr,reg_val); + } + } + + BDK_TRACE(PHY,"loading init script is done\n"); + +} + +static void vitesse_program(bdk_node_t node, int mdio_bus, int phy_addr) +{ + return; +} + +/** + * Setup Vitesse PHYs + * This function sets up one port in a Vitesse VSC8514 + */ +static void setup_vitesse_phy(bdk_node_t node, int mdio_bus, int phy_addr) +{ + /*setting MAC if*/ + bdk_mdio_write(node, mdio_bus, phy_addr, 31, VSC_PHY_GPIO_PAGE); + wr_masked(node,mdio_bus,phy_addr, 19, 0x4000, 0xc000); + bdk_mdio_write(node, mdio_bus, phy_addr, 18, 0x80e0); + + /*Setting media if*/ + bdk_mdio_write(node, mdio_bus, phy_addr, 31, VSC_PHY_STD_PAGE); + // Reg23, 10:8 Select copper, CAT5 copper only + wr_masked(node,mdio_bus,phy_addr, 23, 0x0000, 0x0700); + + // Reg0:15, soft Reset + wr_masked(node,mdio_bus,phy_addr, 0, 0x8000, 0x8000); + int time_out = 100; + while (time_out && bdk_mdio_read(node,mdio_bus,phy_addr, 0) & 0x8000) + { + bdk_wait_usec(100000); + time_out--; + } + + if (time_out == 0) + { + BDK_TRACE(PHY,"setting PHY TIME OUT\n"); + return; + } + else + { + BDK_TRACE(PHY,"Setting a phy port is done\n"); + } + + bdk_mdio_write(node, mdio_bus, phy_addr, 31, VSC_PHY_EXT3_PAGE); + bdk_mdio_write(node, mdio_bus, phy_addr, 16, 0x80); + // Select main registers + bdk_mdio_write(node, mdio_bus, phy_addr, 31, VSC_PHY_STD_PAGE); + + /* + + if (LOOP_INTERNAL) + { + reg0 = bdk_mdio_read(node, mdio_bus, phy_addr, 0); + reg0 = bdk_insert(reg0, 1, 14, 1); + bdk_mdio_write(node, mdio_bus, phy_addr, 0, reg0); + } + + // Far end loopback (External side) + if (LOOP_EXTERNAL) + { + reg23 = bdk_mdio_read(node, mdio_bus, phy_addr, 23); + reg23 = bdk_insert(reg23, 1, 3, 1); + bdk_mdio_write(node, mdio_bus, phy_addr, 23, reg23); + } + + + // Dump registers + if (false) + { + printf("\nVitesse PHY register dump, PHY address %d, mode %s\n", + phy_addr, (qsgmii) ? "QSGMII" : "SGMII"); + int phy_addr = 4; + for (int reg_set = 0; reg_set <= 0x10; reg_set += 0x10) + { + printf("\nDump registers with reg[31]=0x%x\n", reg_set); + bdk_mdio_write(node, mdio_bus, phy_addr, 31, reg_set); + for (int reg=0; reg < 32; reg++) + printf("reg[%02d]=0x%x\n", reg, bdk_mdio_read(node, mdio_bus, phy_addr, reg)); + } + } + */ +} + +//static void vetesse_setup(bdk_node_t node, int qlm, int mdio_bus, int phy_addr) +int bdk_if_phy_vsc8514_setup(bdk_node_t node, int qlm, int mdio_bus, int phy_addr) +{ + /* Check if the PHY is Vetesse PHY we expect */ + int phy_status_1 = bdk_mdio_read(node, mdio_bus, phy_addr, BDK_MDIO_PHY_REG_ID1); + int phy_status_2 = bdk_mdio_read(node, mdio_bus, phy_addr, BDK_MDIO_PHY_REG_ID2); + if (phy_status_1 != 0x0007 || phy_status_2 != 0x0670) + { + bdk_error("The PHY on this board is NOT VSC8514.\n"); + return -1; + } + + /* Check that the GSER mode is SGMII or QSGMII */ + bdk_qlm_modes_t qlm_mode = bdk_qlm_get_mode(node, qlm); + if (qlm_mode != BDK_QLM_MODE_QSGMII_4X1) + return -1; + + vitesse_init_script(node, mdio_bus, phy_addr); + vitesse_program(node, mdio_bus, phy_addr); + + /* VSC8514 just support QSGMII */ + for (int port = 0; port < 4; port++) + setup_vitesse_phy(node, mdio_bus, phy_addr + port); + + return 1; + +} |