From f710c783cb2d81f7c8e99bcfb795e5a21d6e74b8 Mon Sep 17 00:00:00 2001 From: Mike Line Date: Fri, 17 Dec 2010 18:56:40 -0500 Subject: [PATCH] Initial c661x version The ethernet and DDR driver for c661x have been added. --- src/arch/c64x/types.h | 2 + src/cfg/c661x/iblcfg.h | 108 ++++ src/device/c6455/target.h | 12 + src/device/c6457/target.h | 13 + src/device/c6472/target.h | 13 + src/device/c6474/target.h | 13 + src/device/c64x/c64x.s | 42 ++ src/device/c64x/make/makefile | 20 +- src/device/c661x/c661x.c | 532 ++++++++++++++++++ src/device/c661x/c661xinit.c | 65 +++ src/device/c661x/c661xutil.c | 80 +++ src/device/c661x/target.h | 309 ++++++++++ src/device/device.h | 10 + src/driver/eth/net.c | 3 + src/driver/eth/net.h | 2 + src/ethboot/c64x/make/makefile | 4 + src/ethboot/ethboot.c | 64 ++- src/hw/c64x/make/makefile | 32 +- src/hw/c64x/make/makestg2 | 2 +- src/hw/cpdma/cpdma.c | 191 +++++++ src/hw/cpdma/cpdma_api.h | 43 ++ src/hw/cpdma/cpdma_loc.h | 110 ++++ src/hw/cpsw/cpsw.c | 50 ++ src/hw/cpsw/cpsw_api.h | 30 + src/hw/cpsw/cpsw_loc.h | 26 + src/hw/ddrs/emif4/emif4.c | 115 ++++ src/hw/ddrs/emif4/emif4_api.h | 22 + src/hw/ddrs/emif4/emif4_loc.h | 52 ++ src/hw/macs/cpmacsl/gmacsl.c | 140 +++++ src/hw/macs/cpmacsl/gmacsl_api.h | 64 +++ src/hw/macs/cpmacsl/gmacsl_loc.h | 36 ++ src/hw/nands/emif25/nandemif25.c | 201 +++++++ src/hw/nands/emif25/nandemif25_loc.h | 44 ++ src/hw/nands/gpio/nandgpio.c | 2 +- src/hw/nands/nandhwapi.h | 3 +- src/hw/pa/hwpafw_bin.h | 65 +++ src/hw/pa/hwpafwsw.h | 22 + src/hw/pa/pa.c | 124 ++++ src/hw/pa/pa_api.h | 32 ++ src/hw/pa/pa_loc.h | 29 + src/hw/plls/pll014phi/cfgpll.c | 124 ++++ src/hw/plls/pll014phi/cfgpll2.c | 118 ++++ src/hw/plls/pll014phi/pll.c | 152 +++++ src/hw/plls/pll014phi/pllloc.h | 86 +++ src/hw/plls/pllapi.h | 2 + src/hw/pscs/psc2/pscloc.h | 4 - src/hw/qm/qm.c | 213 +++++++ src/hw/qm/qm_api.h | 109 ++++ src/hw/qm/qm_loc.h | 44 ++ src/hw/serdes/serdes.c | 100 ++++ src/hw/serdes/serdes_api.h | 32 ++ src/hw/serdes/serdesloc.h | 37 ++ src/hw/sgmii/sgmii.c | 8 + src/ibl.h | 124 +++- src/make/Makefile | 4 +- src/make/ibl_c661x/i2crom.map.pre | 74 +++ src/make/ibl_c661x/ibl.cmd | 37 ++ src/make/ibl_c661x/ibl.rmd | 11 + src/make/ibl_c661x/ibl_common.inc | 42 ++ src/make/ibl_c661x/ibl_init.cmd | 31 + src/make/ibl_c661x/ibl_init.rmd | 11 + src/make/ibl_c661x/ibl_init_image.rmd | 10 + src/make/ibl_c661x/ibl_init_objs_template.inc | 22 + src/make/ibl_c661x/ibl_objs_template.inc | 62 ++ src/make/makestg1 | 6 +- src/make/makestg2 | 8 +- src/util/i2cConfig/Makefile | 2 +- src/util/i2cConfig/makestg2 | 30 +- src/util/i2cRead/Makefile | 2 +- src/util/i2cRead/makestg2 | 2 +- src/util/i2cWrite/Makefile | 2 +- src/util/i2cWrite/makestg2 | 30 +- src/util/romparse/romparse.c | 21 +- src/util/romparse/romparse.h | 2 + src/util/romparse/rparse.flex | 4 + src/util/romparse/rparse.y | 5 + 76 files changed, 4262 insertions(+), 36 deletions(-) create mode 100644 src/cfg/c661x/iblcfg.h create mode 100644 src/device/c64x/c64x.s create mode 100644 src/device/c661x/c661x.c create mode 100644 src/device/c661x/c661xinit.c create mode 100644 src/device/c661x/c661xutil.c create mode 100644 src/device/c661x/target.h create mode 100644 src/hw/cpdma/cpdma.c create mode 100644 src/hw/cpdma/cpdma_api.h create mode 100644 src/hw/cpdma/cpdma_loc.h create mode 100644 src/hw/cpsw/cpsw.c create mode 100644 src/hw/cpsw/cpsw_api.h create mode 100644 src/hw/cpsw/cpsw_loc.h create mode 100644 src/hw/ddrs/emif4/emif4.c create mode 100644 src/hw/ddrs/emif4/emif4_api.h create mode 100644 src/hw/ddrs/emif4/emif4_loc.h create mode 100644 src/hw/macs/cpmacsl/gmacsl.c create mode 100644 src/hw/macs/cpmacsl/gmacsl_api.h create mode 100644 src/hw/macs/cpmacsl/gmacsl_loc.h create mode 100644 src/hw/nands/emif25/nandemif25.c create mode 100644 src/hw/nands/emif25/nandemif25_loc.h create mode 100644 src/hw/pa/hwpafw_bin.h create mode 100644 src/hw/pa/hwpafwsw.h create mode 100644 src/hw/pa/pa.c create mode 100644 src/hw/pa/pa_api.h create mode 100644 src/hw/pa/pa_loc.h create mode 100644 src/hw/plls/pll014phi/cfgpll.c create mode 100644 src/hw/plls/pll014phi/cfgpll2.c create mode 100644 src/hw/plls/pll014phi/pll.c create mode 100644 src/hw/plls/pll014phi/pllloc.h create mode 100644 src/hw/qm/qm.c create mode 100644 src/hw/qm/qm_api.h create mode 100644 src/hw/qm/qm_loc.h create mode 100644 src/hw/serdes/serdes.c create mode 100644 src/hw/serdes/serdes_api.h create mode 100644 src/hw/serdes/serdesloc.h create mode 100644 src/make/ibl_c661x/i2crom.map.pre create mode 100644 src/make/ibl_c661x/ibl.cmd create mode 100644 src/make/ibl_c661x/ibl.rmd create mode 100644 src/make/ibl_c661x/ibl_common.inc create mode 100644 src/make/ibl_c661x/ibl_init.cmd create mode 100644 src/make/ibl_c661x/ibl_init.rmd create mode 100644 src/make/ibl_c661x/ibl_init_image.rmd create mode 100644 src/make/ibl_c661x/ibl_init_objs_template.inc create mode 100644 src/make/ibl_c661x/ibl_objs_template.inc diff --git a/src/arch/c64x/types.h b/src/arch/c64x/types.h index 652238d..eb78227 100644 --- a/src/arch/c64x/types.h +++ b/src/arch/c64x/types.h @@ -92,7 +92,9 @@ typedef unsigned int Uint32; /* TI boot types */ typedef unsigned char UINT8; typedef unsigned short UINT16; +typedef short SINT16; typedef unsigned int UINT32; +typedef int SINT32; /* Types from evm driver */ diff --git a/src/cfg/c661x/iblcfg.h b/src/cfg/c661x/iblcfg.h new file mode 100644 index 0000000..1edbe12 --- /dev/null +++ b/src/cfg/c661x/iblcfg.h @@ -0,0 +1,108 @@ +/* + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * 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 Texas Instruments Incorporated 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 IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + +/************************************************************************** + * FILE PURPOSE: Provide build time configurations for the IBL + ************************************************************************** + * FILE NAME: iblcfg.h + * + * DESCRIPTION: Build time configuration + * + * @file iblcfg.h + * + * @brief + * Build time configurations for the c661x ibl are defined + * + ***************************************************************************/ +#ifndef IBLCFG_H +#define IBLCFG_H + +/** + * @brief The maximum number of UDP sockets in the system + */ +#define MAX_UDP_SOCKET 3 + + +/** + * @brief The maximum number of timers in the system + */ +#define MAX_TIMER_BLOCKS 5 + + +/** + * @brief The size in bytes of the internal stream buffer + */ +#define MAX_SIZE_STREAM_BUFFER 1520 + + +/** + * @brief The maximum number of functions supported for BIS mode + */ +#define MAX_BIS_FUNCTION_SUPPORT 3 + + +/** + * @brief No I/O sections accepted in boot table format + */ +#define BOOTCONFIG_NO_BTBL_IO + +/** + * @brief Estimates of operating parameters. Actual values will be known once they are + * read from the i2c. + */ +#define IBL_CFG_I2C_DEV_FREQ_MHZ 1200 +#define IBL_CFG_I2C_CLK_FREQ_KHZ 100 +#define IBL_CFG_I2C_OWN_ADDR 10 +#define IBL_CFG_I2C_ADDR_DELAY 0x100 /* Delay between sending the address and reading data */ + + +/** + * @brief The default location for the i2c map information can be overridden during make + */ +#ifndef IBL_CFG_I2C_MAP_TABLE_DATA_BUS_ADDR + #define IBL_CFG_I2C_MAP_TABLE_DATA_BUS_ADDR 0x50 +#endif + + +#ifndef IBL_CFG_I2C_MAP_TABLE_DATA_ADDR + #define IBL_CFG_I2C_MAP_TABLE_DATA_ADDR 0x420 +#endif + + +#endif + + diff --git a/src/device/c6455/target.h b/src/device/c6455/target.h index 34db4eb..bffe7f0 100644 --- a/src/device/c6455/target.h +++ b/src/device/c6455/target.h @@ -173,5 +173,17 @@ #define DEVICE_I2C_MODULE_DIVISOR 6 +/** + * @brief + * Register access macros + */ +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + + diff --git a/src/device/c6457/target.h b/src/device/c6457/target.h index 5988bb0..fc12659 100644 --- a/src/device/c6457/target.h +++ b/src/device/c6457/target.h @@ -185,3 +185,16 @@ #define DEVICE_I2C_BASE 0x02b04000 #define DEVICE_I2C_MODULE_DIVISOR 6 + +/** + * @brief + * Register access macros + */ +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + + diff --git a/src/device/c6472/target.h b/src/device/c6472/target.h index 5b86007..d779fa1 100644 --- a/src/device/c6472/target.h +++ b/src/device/c6472/target.h @@ -177,3 +177,16 @@ #define DEVICE_I2C_BASE 0x02b04000 #define DEVICE_I2C_MODULE_DIVISOR 6 + +/** + * @brief + * Register access macros + */ +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + + diff --git a/src/device/c6474/target.h b/src/device/c6474/target.h index e1612b6..1e6b736 100644 --- a/src/device/c6474/target.h +++ b/src/device/c6474/target.h @@ -185,3 +185,16 @@ #define DEVICE_I2C_BASE 0x02b04000 #define DEVICE_I2C_MODULE_DIVISOR 6 + +/** + * @brief + * Register access macros + */ +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + + diff --git a/src/device/c64x/c64x.s b/src/device/c64x/c64x.s new file mode 100644 index 0000000..6862ea2 --- /dev/null +++ b/src/device/c64x/c64x.s @@ -0,0 +1,42 @@ +; /** +; * @file c64x.s +; * +; * @breif +; * Assembly functions for c64x compatible devices +; */ + + .text + +; ******************************************************************************** +; * Provide a rough delay, in CPU cycles. +; * On Entry: +; * A4 = number of cycles to delay +; ******************************************************************************** + .def _chipDelay32 +_chipDelay32: + + ZERO .L2 B4 + SHRU .S1 A4,3,A0 + CMPLTU .L2X B4,A4,B0 + [!A0] BNOP .S1 cend, 5 + + [!B0] BNOP .S1 cend, 3 + MVKL .S1 1,A5 + MVKH .S1 1,A5 + + +dosub: + SUB .L1 A0,A5,A0 + NOP 2 + [A0] BNOP .S1 dosub,5 + + + +cend: + RETNOP.S2 B3, 5 + + + + + + diff --git a/src/device/c64x/make/makefile b/src/device/c64x/make/makefile index 1fa35d4..da83c7b 100644 --- a/src/device/c64x/make/makefile +++ b/src/device/c64x/make/makefile @@ -48,6 +48,8 @@ endif ECODIR= $(IBL_ROOT)/device +ASMSRC= c64x.s + # For no target set CSRC to all sources for clean ifeq ($(TARGET),c6472) CSRC= c6472.c c6472init.c @@ -63,10 +65,14 @@ else else ifeq ($(TARGET),c6457) CSRC= c6457.c - else - CSRC= c6472.c c6455.c c6474.c c6474l.c c6457.c - endif - endif + else + ifeq ($(TARGET),c661x) + CSRC= c661x.c c661xinit.c c661xutil.c + else + CSRC= c6472.c c6455.c c6474.c c6474l.c c6457.c c6472init.c c6455init.c c6474init.c c661x.c c661xinit.c c661xutil.c + endif + endif + endif endif endif endif @@ -78,6 +84,7 @@ include $(IBL_ROOT)/make/$(ARCH)/makeeco.mk C6X_C_DIR= $(IBL_ROOT)/device/$(TARGET) +C6X_C_DIR+= ;$(IBL_ROOT)/cfg/$(TARGET) C6X_C_DIR+= ;$(IBL_ROOT)/device C6X_C_DIR+= ;$(IBL_ROOT) C6X_C_DIR+= ;$(IBL_ROOT)/arch/$(ARCH) @@ -86,6 +93,11 @@ C6X_C_DIR+= ;$(IBL_ROOT)/hw/plls C6X_C_DIR+= ;$(IBL_ROOT)/hw/pscs C6X_C_DIR+= ;$(IBL_ROOT)/hw/gpio C6X_C_DIR+= ;$(IBL_ROOT)/hw/ddrs/emif31 +C6X_C_DIR+= ;$(IBL_ROOT)/hw/qm +C6X_C_DIR+= ;$(IBL_ROOT)/hw/cpdma +C6X_C_DIR+= ;$(IBL_ROOT)/hw/pa +C6X_C_DIR+= ;$(IBL_ROOT)/hw/serdes +C6X_C_DIR+= ;$(IBL_ROOT)/driver/eth export C6X_C_DIR vpath % $(IBL_ROOT)/device/$(TARGET) diff --git a/src/device/c661x/c661x.c b/src/device/c661x/c661x.c new file mode 100644 index 0000000..954c079 --- /dev/null +++ b/src/device/c661x/c661x.c @@ -0,0 +1,532 @@ +/* + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * 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 Texas Instruments Incorporated 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 IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + +/************************************************************************************ + * FILE PURPOSE: C661x Device Specific functions + ************************************************************************************ + * FILE NAME: c661x.c + * + * DESCRIPTION: Implements the device specific functions for the IBL + * + * @file c661x.c + * + * @brief + * This file implements the device specific functions for the IBL + * + ************************************************************************************/ +#include "ibl.h" +#include "iblloc.h" +#include "iblcfg.h" +#include "device.h" +#include "pllapi.h" +#include "emif31api.h" +#include "pscapi.h" +#include "gpio.h" +#include "qm_api.h" +#include "cpdma_api.h" +#include "pa_api.h" +#include "serdes_api.h" +#include "net.h" +#include + +extern cregister unsigned int DNUM; + + +/** + * @brief Determine if an address is local + * + * @details + * Examines an input address to determine if it is a local address. Using the largest + * L2 size on the 6616. + */ +bool address_is_local (Uint32 addr) +{ + /* L2 */ + if ((addr >= 0x00800000) && (addr < 0x00900000)) + return (TRUE); + + /* L1P */ + if ((addr >= 0x00e00000) && (addr < 0x00e08000)) + return (TRUE); + + /* L2D */ + if ((addr >= 0x00f00000) && (addr < 0x00f08000)) + return (TRUE); + + return (FALSE); + +} + + +/** + * @brief Convert a local l1d, l1p or l2 address to a global address + * + * @details + * The global address is formed. If the address is not local then + * the input address is returned + */ +Uint32 deviceLocalAddrToGlobal (Uint32 addr) +{ + + if (address_is_local (addr)) + addr = (1 << 28) | (DNUM << 24) | addr; + + return (addr); + +} + + +/** + * @brief + * Enable the DDR + * + * @details + * The DDR controller on the c661x is an emif 4.0. The controller is + * initialized directly with the supplied values + */ +void deviceDdrConfig (void) +{ + /* The emif registers must be made visible. MPAX mapping 2 is used */ + DEVICE_REG_XMPAX_L(2) = 0x10000000 | 0xf6; /* replacement addr + perm*/ + DEVICE_REG_XMPAX_H(2) = 0x2100000B; /* base addr + seg size (64KB)*/ + + if (ibl.ddrConfig.configDdr != 0) + hwEmif4p0Enable (&ibl.ddrConfig.uEmif.emif4p0); + +} + + +/** + * @brief Power up a peripheral + * + * @details + * Boot peripherals are powered up + */ +int32 devicePowerPeriph (int32 modNum) +{ + /* If the input value is < 0 there is nothing to power up */ + if (modNum < 0) + return (0); + + + if (modNum >= TARGET_PWR_MAX_MOD) + return (-1); + + return ((int32)pscEnableModule(modNum)); + +} + + +/** + * @brief Enable the pass through version of the nand controller + * + * @details On the evm the nand controller is enabled by setting + * gpio 14 high + */ +#ifndef EXCLUDE_NAND +int32 deviceConfigureForNand(void) +{ + return (0); + +} + +/** + * @brief + * Return the base memory address for NAND in a given chip select space + */ +uint32 deviceNandMemBase (int32 cs) +{ + switch (cs) { + + case 2: return (TARGET_MEM_NAND_CS_2); + + case 3: return (TARGET_MEM_NAND_CS_3); + + case 4: return (TARGET_MEM_NAND_CS_4); + + case 5: return (TARGET_MEM_NAND_CS_5); + + } + + return (0xffffffff); + +} + +/** + * @brief + * Return the PSC number for NAND. Only 6618 has NAND + */ +Int32 deviceNandPscNum (void) +{ + Uint32 v; + + v = *((Uint32 *)DEVICE_JTAG_ID_REG); + if (v == DEVICE_C6618_JTAG_ID_VAL) + return (TARGET_PWR_NAND_C6618); + + /* Return a negative number to indicate no PSC module is associated with NAND */ + return (-1); + +} + + +#endif + + +/** + * @brief + * The e-fuse mac address is loaded + */ +void deviceLoadDefaultEthAddress (uint8 *maddr) +{ + uint32 macA, macB; + + /* Read the e-fuse mac address */ + macA = *((uint32 *)0x2620110); + macB = *((uint32 *)0x2620114); + + maddr[0] = (macB >> 8) & 0xff; + maddr[1] = (macB >> 0) & 0xff; + maddr[2] = (macA >> 24) & 0xff; + maddr[3] = (macA >> 16) & 0xff; + maddr[4] = (macA >> 8) & 0xff; + maddr[5] = (macA >> 0) & 0xff; +} + + +/** + * @brief + * Compile time queue manager information + */ +#define DEVICE_NUM_RX_CPPIS 1 +#define DEVICE_NUM_TX_CPPIS 1 +#define DEVICE_NUM_CPPIS (DEVICE_NUM_RX_CPPIS + DEVICE_NUM_TX_CPPIS) + +/* The linking RAM */ +#pragma DATA_SECTION(qm_linkram_buf, ".linkram") +#pragma DATA_ALIGN(qm_linkram_buf, 16) +uint8 qm_linkram_buf[DEVICE_NUM_CPPIS * 2 * (sizeof(uint32)/sizeof(uint8))]; + + +/* The CPPI RAM */ +#pragma DATA_SECTION(qm_cppi_buf, ".cppi") +#pragma DATA_ALIGN(qm_cppi_buf, 16) +uint8 qm_cppi_buf[QM_DESC_SIZE_BYTES * DEVICE_NUM_CPPIS]; + + +/* The rx data buffers */ +#pragma DATA_SECTION(qm_buffer, ".mac_buffer") +#pragma DATA_ALIGN(qm_buffer, 16) +uint8 qm_buffer[MAX_SIZE_STREAM_BUFFER * DEVICE_NUM_RX_CPPIS]; + +const qmConfig_t qmConfig = { + (UINT32) qm_linkram_buf, + sizeof (qm_cppi_buf), + (UINT32) qm_cppi_buf, + + DEVICE_NUM_CPPIS, + DEVICE_QM_FREE_Q +}; + +/** + * @brief + * Return the queue manager memory configuration information + */ +void *targetGetQmConfig (void) +{ + return ((void *)&qmConfig); +} + +/** + * @brief + * Attach a packet buffer to each descriptor and push onto the linked buffer queue + */ +void targetInitQs (void) +{ + int32 i; + qmHostDesc_t *hd; + + for (i = 0; i < DEVICE_NUM_RX_CPPIS; i++) { + + hd = hwQmQueuePop (DEVICE_QM_FREE_Q); + hd->buffLen = sizeof (qm_buffer) / DEVICE_NUM_CPPIS; + hd->buffPtr = (UINT32) &(qm_buffer[MAX_SIZE_STREAM_BUFFER * i]); + hd->nextBDPtr = 0; + hd->origBufferLen = MAX_SIZE_STREAM_BUFFER; + hd->origBuffPtr = hd->buffPtr; + + hwQmQueuePush (hd, DEVICE_QM_LNK_BUF_Q, QM_DESC_SIZE_BYTES); + + } + + + for (i = 0; i < DEVICE_NUM_TX_CPPIS; i++) { + + hd = hwQmQueuePop (DEVICE_QM_FREE_Q); + hd->buffLen = 0; + hd->buffPtr = 0; + hd->nextBDPtr = 0; + hd->origBufferLen = 0; + hd->origBuffPtr = 0; + + hwQmQueuePush (hd, DEVICE_QM_TX_Q, QM_DESC_SIZE_BYTES); + + } + + +} + + + +const cpdmaRxCfg_t cpdmaEthRxCfg = { + + DEVICE_PA_CDMA_RX_CHAN_CFG_BASE, /* Base address of PA CPDMA rx config registers */ + DEVICE_PA_CDMA_RX_NUM_CHANNELS, /* Number of rx channels */ + + DEVICE_PA_CDMA_RX_FLOW_CFG_BASE, /* Base address of PA CPDMA rx flow registers */ + DEVICE_PA_CDMA_RX_NUM_FLOWS, /* Number of rx flows */ + + 0, /* Queue manager for descriptor / buffer for received packets */ + DEVICE_QM_LNK_BUF_Q, /* Queue of descriptors /buffers for received packets */ + + 0, /* Queue manager for received packets */ + DEVICE_QM_RCV_Q, /* Queue for received packets (overridden by PA) */ + + DEVICE_RX_CDMA_TIMEOUT_COUNT /* Teardown maximum loop wait */ +}; + + +/** + * @brief + * Return the cpdma configuration information + */ +void *targetGetCpdmaRxConfig (void) +{ + return ((void *)&cpdmaEthRxCfg); + +} + + +const cpdmaTxCfg_t cpdmaEthTxCfg = { + + DEVICE_PA_CDMA_GLOBAL_CFG_BASE, /* Base address of global config registers */ + DEVICE_PA_CDMA_TX_CHAN_CFG_BASE, /* Base address of PA CPDMA tx config registers */ + DEVICE_PA_CDMA_TX_NUM_CHANNELS /* Number of tx channels */ + +}; + + +/** + * @brief + * return the tx cpdma configuration information + */ +void *targetGetCpdmaTxConfig (void) +{ + return ((void *)&cpdmaEthTxCfg); + +} + +/** + * @brief + * Configure the PA + */ +void targetPaConfig (uint8 *macAddr) +{ + paConfig_t paCfg; + qmHostDesc_t *hd; + SINT16 ret; + + /* Filter everything except the desired mac address and the broadcast mac */ + paCfg.mac0ms = ((uint32)macAddr[0] << 24) | ((uint32)macAddr[1] << 16) | ((uint32)macAddr[2] << 8) | (uint32)(macAddr[3]); + paCfg.mac0ls = ((uint32)macAddr[4] << 24) | ((uint32)macAddr[5] << 16); + + paCfg.mac1ms = 0xffffffff; + paCfg.mac1ls = 0xffff0000; + + paCfg.rxQnum = DEVICE_QM_RCV_Q; + + /* Form the configuration command in a buffer linked to a descriptor */ + hd = hwQmQueuePop (DEVICE_QM_LNK_BUF_Q); + paCfg.cmdBuf = (uint8 *)hd->origBuffPtr; + + ret = hwPaEnable (&paCfg); + if (ret != 0) { + iblStatus.iblFail = ibl_FAIL_CODE_PA; + return; + } + + + /* Send the command to the PA through the QM */ + hd->softwareInfo0 = PA_MAGIC_ID; + hd->buffLen = 16; + QM_DESC_DESCINFO_SET_PKT_LEN(hd->descInfo, 16); + + /* Set the return Queue */ + QM_DESC_PINFO_SET_QM (hd->packetInfo, 0); + QM_DESC_PINFO_SET_QUEUE (hd->packetInfo, DEVICE_QM_LNK_BUF_Q); + + hwQmQueuePush (hd, DEVICE_QM_PA_CFG_Q, QM_DESC_SIZE_BYTES); + + +} + +/** + * @brief + * Chip level SGMII serdes configuration + * + * @details + * Both lanes are always setup, regardless of the port value + */ +void targetSgmiiSerdesConfig (int32 port, void *viblSgmii) +{ + serdesConfig_t scfg; + iblSgmii_t *sgmii = (iblSgmii_t *)viblSgmii; + + scfg.cfg = sgmii->auxConfig; + scfg.nLanes = 2; + scfg.rxCfg[0] = scfg.rxCfg[1] = sgmii->rxConfig; + scfg.txCfg[0] = scfg.txCfg[1] = sgmii->txConfig; + + hwSerdesConfig (TARGET_SGMII_SERDES_BASE, &scfg); + + hwSerdesWaitLock (TARGET_SGMII_SERDES_STATUS_BASE); + +} + + +Int32 targetMacSend (void *vptr_device, Uint8* buffer, int num_bytes) +{ + qmHostDesc_t *hd; + NET_DRV_DEVICE *ptr_device = (NET_DRV_DEVICE *)vptr_device; + int i; + + + for (i = 0, hd = NULL; hd == NULL; i++, chipDelay32 (1000)) + hd = hwQmQueuePop (DEVICE_QM_TX_Q); + + if (hd == NULL) + return (-1); + + QM_DESC_DESCINFO_SET_PKT_LEN(hd->descInfo, num_bytes); + + hd->buffLen = num_bytes; + hd->origBufferLen = num_bytes; + + hd->buffPtr = deviceLocalAddrToGlobal((UINT32)buffer); + hd->origBuffPtr = deviceLocalAddrToGlobal((UINT32)buffer); + + + /* Return the descriptor back to the transmit queue */ + QM_DESC_PINFO_SET_QM(hd->packetInfo, 0); + QM_DESC_PINFO_SET_QUEUE(hd->packetInfo, DEVICE_QM_TX_Q); + + hwQmQueuePush (hd, DEVICE_QM_ETH_TX_Q, QM_DESC_SIZE_BYTES); + + return (0); + +} + + +Int32 targetMacRcv (void *vptr_device, UINT8 *buffer) +{ + Int32 pktSizeBytes; + qmHostDesc_t *hd; + NET_DRV_DEVICE *ptr_device = (NET_DRV_DEVICE *)vptr_device; + + hd = hwQmQueuePop (DEVICE_QM_RCV_Q); + if (hd == NULL) + return (0); + + pktSizeBytes = QM_DESC_DESCINFO_GET_PKT_LEN(hd->descInfo); + iblMemcpy ((void *)buffer, (void *)hd->buffPtr, pktSizeBytes); + + hd->buffLen = hd->origBufferLen; + hd->buffPtr = hd->origBuffPtr; + + hwQmQueuePush (hd, DEVICE_QM_LNK_BUF_Q, QM_DESC_SIZE_BYTES); + + return (pktSizeBytes); + +} + +void targetFreeQs (void) +{ + qmHostDesc_t *hd; + + do { + + hd = hwQmQueuePop (DEVICE_QM_FREE_Q); + + } while (hd != NULL); + + do { + + hd = hwQmQueuePop (DEVICE_QM_LNK_BUF_Q); + + } while (hd != NULL); + + do { + + hd = hwQmQueuePop (DEVICE_QM_RCV_Q); + + } while (hd != NULL); + + do { + + hd = hwQmQueuePop (DEVICE_QM_TX_Q); + + } while (hd != NULL); + +} + + + + + + + + + + + + + + + + + + diff --git a/src/device/c661x/c661xinit.c b/src/device/c661x/c661xinit.c new file mode 100644 index 0000000..a491647 --- /dev/null +++ b/src/device/c661x/c661xinit.c @@ -0,0 +1,65 @@ +/** + * @file c661xinit.c + * + * @brief + * c661x functions used during the initial stage of the ibl load + * + */ +#include "ibl.h" +#include "device.h" +#include "pllapi.h" + +/** + * @brief Configure the PLLs + * + * @details + * The three PLLs are enabled. Only the main PLL has the ability to configure + * the multiplier and dividers. + */ +void devicePllConfig (void) +{ + if (ibl.pllConfig[ibl_MAIN_PLL].doEnable == TRUE) + hwPllSetPll (MAIN_PLL, + ibl.pllConfig[ibl_MAIN_PLL].prediv, + ibl.pllConfig[ibl_MAIN_PLL].mult, + ibl.pllConfig[ibl_MAIN_PLL].postdiv); + + if (ibl.pllConfig[ibl_DDR_PLL].doEnable == TRUE) + hwPllSetCfg2Pll (DEVICE_PLL_BASE(DDR_PLL), + ibl.pllConfig[ibl_DDR_PLL].prediv, + ibl.pllConfig[ibl_DDR_PLL].mult, + ibl.pllConfig[ibl_DDR_PLL].postdiv, + ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz, + ibl.pllConfig[ibl_DDR_PLL].pllOutFreqMhz); + + if (ibl.pllConfig[ibl_NET_PLL].doEnable == TRUE) + hwPllSetCfgPll (DEVICE_PLL_BASE(NET_PLL), + ibl.pllConfig[ibl_NET_PLL].prediv, + ibl.pllConfig[ibl_NET_PLL].mult, + ibl.pllConfig[ibl_NET_PLL].postdiv, + ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz, + ibl.pllConfig[ibl_NET_PLL].pllOutFreqMhz); + + +} + + +/** + * @brief + * Return the endian status of the device + * + * @details + * Returns true if the device is executing in little endian mode + */ +extern cregister volatile unsigned int CSR; + +bool deviceIsLittleEndian (void) +{ + if ((CSR & (1 << 8)) == 0) + return (FALSE); + + return (TRUE); + +} + + diff --git a/src/device/c661x/c661xutil.c b/src/device/c661x/c661xutil.c new file mode 100644 index 0000000..0eca68d --- /dev/null +++ b/src/device/c661x/c661xutil.c @@ -0,0 +1,80 @@ +/** + * @file c661xutil.c + * + * @brief + * c661x functions used by both the ibl and utility programs + */ + +#include "device.h" +#include "pllapi.h" + + +/** + * @brief + * Configure the predivider for the main PLL, which resides outside the PLL controller + */ +SINT16 chipPllSetExternalPrediv(UINT16 pllNum, UINT32 predivRegVal) +{ + UINT32 reg; + + reg = DEVICE_REG32_R (DEVICE_MAIN_PLL_CTL_0); + reg = BOOT_SET_BITFIELD(reg, predivRegVal, 5, 0); + DEVICE_REG32_W (DEVICE_MAIN_PLL_CTL_0, reg); + + + return (0); + +} /* chipPllSetExternalPrediv */ + + +/** + * @brief + * Configure the bandwidth adjustment for the main PLL, which resides outside the PLL controller + */ +SINT16 chipPllExternalBwAdj (UINT16 pllNum, UINT16 mult) +{ + UINT32 reg; + UINT32 bwAdj; + + bwAdj = (mult >> 1) - 1; + + reg = DEVICE_REG32_R (DEVICE_MAIN_PLL_CTL_0); + reg = BOOT_SET_BITFIELD(reg, bwAdj & 0x00ff, 31, 24); + DEVICE_REG32_W (DEVICE_MAIN_PLL_CTL_0, reg); + + reg = DEVICE_REG32_R (DEVICE_MAIN_PLL_CTL_1); + reg = BOOT_SET_BITFIELD(reg, bwAdj >> 8, 3, 0); + DEVICE_REG32_W (DEVICE_MAIN_PLL_CTL_1, reg); + + return (0); + +} /* chipPllExternalBwAdj */ + + +/** + * @brief + * Configure the multiplier fields for the main PLL which reside outside the PLL controller + */ +UINT32 chipPllExternalMult (UINT16 pllNum, UINT16 mult) +{ + UINT32 pmult; + UINT32 reg; + UINT32 v; + + + pmult = mult-1; + + v = BOOT_READ_BITFIELD(pmult, 12, 6); + + + reg = DEVICE_REG32_R (DEVICE_MAIN_PLL_CTL_0); + reg = BOOT_SET_BITFIELD(reg, v, 18, 12); + DEVICE_REG32_W (DEVICE_MAIN_PLL_CTL_0, reg); + + + v = BOOT_READ_BITFIELD(pmult, 5, 0); + + return (v); + +} /* chipPllExternalMult */ + diff --git a/src/device/c661x/target.h b/src/device/c661x/target.h new file mode 100644 index 0000000..3b34bc8 --- /dev/null +++ b/src/device/c661x/target.h @@ -0,0 +1,309 @@ +/* + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * 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 Texas Instruments Incorporated 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 IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + + +/************************************************************************** + * FILE PURPOSE: Target specific definitions + ************************************************************************** + * FILE NAME: target.h + * + * DESCRIPTION: This file defines target specific values used by low level + * drivers. + * + * @file target.h + * + * @brief + * Low level target specific values are defined + * + ***************************************************************************/ +#ifndef _TARGET_H +#define _TARGET_H +#include "types.h" + + +/** + * @brief + * Device EMAC definitions + */ + + +/** + * @brief + * Device Timer definitions + */ +#define TIMER0_BASE 0x02200000u + +#define TIMER_INPUT_DIVIDER 6 /* Timer driven from cpu clock / 6 */ + + +/** + * @def MAIN_PLL + */ +#define MAIN_PLL 0 /**< The index to the main PLL */ + +/** + * @def NET_PLL + */ +#define NET_PLL 1 /**< The index to the network PLL */ + +/** + * @def DDR_PLL + */ +#define DDR_PLL 2 /**< The index to the DDR PLL */ + + +/** + * @brief + * Device PLL definitions + */ +#define DEVICE_PLL_BASE(x) ((x) == MAIN_PLL ? 0x2310000 : ((x) == NET_PLL ? 0x2620338 : 0x2620330)) +#define DEVICE_MAIN_PLL_CTL_0 0x2620328 +#define DEVICE_MAIN_PLL_CTL_1 0x262032c + + +/** + * @brief + * The c661x devices use a register external to the PLL controller for prediv configuration + */ +#define chipPllExternalPrediv(x) TRUE + +/** + * @brief + * Device PSC definitions + */ +#define DEVICE_PSC_BASE 0x02350000u + + +/** + * @brief + * The PSC number for the PA sub-system */ +#define TARGET_PWR_PA 7 + +/** + * @brief + * The PSC number for the SGMII */ +#define TARGET_PWR_ETH(x) 8 + +/** + * @brief + * The PSC numbers for EMIF16 and SPI vary between devices. The devices are run time + * identified by reading the JTAG ID register + */ +#define DEVICE_C6616_JTAG_ID_VAL 0x9d02f +#define DEVICE_C6618_JTAG_ID_VAL 0x9e02f +#define DEVICE_JTAG_ID_REG 0x2620018 + + +/** + * @brief + * The PSC number for NAND depends on the device + */ +#define TARGET_PWR_NAND deviceNandPscNum() +#define TARGET_PWR_NAND_C6618 3 + +/* + * @brief + * The PSC number for SPI depends on the device + */ +#define TARGET_PWR_SPI deviceSpiPscNum() + +/** + * @brief + * Flag to indicate timer 0 power up requested. The time is always on in the 6472 + */ +#define TARGET_PWR_TIMER_0 -1 + +/** + * @brief + * Device DDR controller definitions + */ +#define DEVICE_EMIF4_BASE 0x21000000 + +/** + * @brief + * Device EMIF 2.5 controller definitions + */ +#define DEVICE_EMIF25_BASE 0x20c00000 + +/** + * @brief + * NAND memory regions + */ +#define TARGET_MEM_NAND_CS_2 0x70000000 +#define TARGET_MEM_NAND_CS_3 0x74000000 +#define TARGET_MEM_NAND_CS_4 0x78000000 +#define TARGET_MEM_NAND_CS_5 0x7c000000 +uint32 deviceNandMemBase (int32 cs); +#define TARGET_SHFL(x) _shfl(x) /* The shuffle intrinsic */ + + +/** + * @brief + * The highest module number. The value for nyquist is used + */ +#define TARGET_PWR_MAX_MOD 30 + + +/** + * @brief + * The base address of MDIO + */ +#define TARGET_MDIO_BASE 0x2090300 + +/** + * @brief + * The number of external ethernet ports + */ +#define TARGET_EMAC_N_PORTS 2 + + + +/** + * @brief + * The base address of the I2C peripheral, and the module divisor of the cpu clock + */ +#define DEVICE_I2C_BASE 0x02530000 +#define DEVICE_I2C_MODULE_DIVISOR 6 + +/** + * @brief + * Prototypes for the PLL functions handled outside the main PLL registers + */ +SINT16 chipPllSetExternalPrediv(UINT16 pllNum, UINT32 predivRegVal); +SINT16 chipPllExternalBwAdj (UINT16 pllNum, UINT16 mult); +UINT32 chipPllExternalMult (UINT16 pllNum, UINT16 mult); + + +/** + * @brief + * Hardware network subsystem support, ethernet switch + */ +#define DEVICE_CPSW +#define DEVICE_CPSW_NUM_PORTS 3 /* 3 switch ports */ +#define DEVICE_CPSW_BASE (0x02090800) +#define targetGetSwitchCtl() CPSW_CTL_P0_ENABLE /* Enable port 0 */ +#define targetGetSwitchMaxPktSize() 9000 + +#define DEVICE_QM +#define DEVICE_QM_MANAGER_BASE 0x02a68000 +#define DEVICE_QM_DESC_SETUP_BASE 0x02a6a000 +#define DEVICE_QM_MANAGER_QUEUES_BASE 0x02a20000 +#define DEVICE_QM_MANAGER_Q_PROXY_BASE 0x02a40000 +#define DEVICE_QM_QUEUE_STATUS_BASE 0x02a00000 +#define DEVICE_QM_NUM_LINKRAMS 2 +#define DEVICE_QM_NUM_MEMREGIONS 20 +void *targetGetQmConfig(void); +void targetInitQs (void); + +#define chipLmbd(x,y) _lmbd(x,y) + + + + +#define DEVICE_CPDMA + +#define DEVICE_PA_CDMA_GLOBAL_CFG_BASE 0x02004000 +#define DEVICE_PA_CDMA_TX_CHAN_CFG_BASE 0x02004400 +#define DEVICE_PA_CDMA_RX_CHAN_CFG_BASE 0x02004800 +#define DEVICE_PA_CDMA_RX_FLOW_CFG_BASE 0x02005000 + +#define DEVICE_PA_CDMA_RX_NUM_CHANNELS 24 +#define DEVICE_PA_CDMA_RX_NUM_FLOWS 32 +#define DEVICE_PA_CDMA_TX_NUM_CHANNELS 9 + + +#define DEVICE_QM_FREE_Q 910 +#define DEVICE_QM_LNK_BUF_Q 911 +#define DEVICE_QM_RCV_Q 912 +#define DEVICE_QM_TX_Q 913 +#define DEVICE_QM_PA_CFG_Q 640 +#define DEVICE_QM_ETH_TX_Q 648 + +#define DEVICE_RX_CDMA_TIMEOUT_COUNT 1000 + + + +#define DEVICE_PA +#define DEVICE_PA_BASE 0x02000000 +#define DEVICE_PA_NUM_PDSPS 6 +#define DEVICE_PA_RUN_CHECK_COUNT 100 /* Number of loops to verify PA firmware is running */ +#define DEVICE_PA_PLL_BASE 0x02620338 +#define chipLower8(x) ((x) & 0x00ff) + + +#define TARGET_SGMII_EXTERNAL_SERDES +#define TARGET_SGMII_BASE_ADDRESSES { 0x02090100, 0x02090200 } +#define TARGET_SGMII_SERDES_BASE 0x2620340 +#define TARGET_SGMII_SERDES_STATUS_BASE 0x2620158 +#define TARGET_SGMII_SOFT_RESET 0x04 +#define TARGET_SGMII_CONTROL 0x10 +#define TARGET_SGMII_MR_ADV_ABILITY 0x18 +void targetSgmiiSerdesConfig (int32 port, void *cfg); +#define chipKickOpenSerdes(x) *((uint32 *)0x2620038) = 0x83e70b13; *((uint32 *)0x262003c) = 0x95a4f1e0 +#define chipKickClosedSerdes(x) ; /* never lock the registers */ +#define TARGET_SERDES_LOCK_DELAY (1600*1000) + +#define DEVICE_EMACSL_BASE(x) (0x02090900 + (x)*0x040) +#define DEVICE_N_GMACSL_PORTS 2 +#define DEVICE_EMACSL_RESET_POLL_COUNT 100 +Int32 targetMacSend (void *ptr_device, Uint8* buffer, int num_bytes); +Int32 targetMacRcv (void *ptr_device, UINT8 *buffer); + +#define DEVICE_SS +#define DEVICE_PSTREAM_CFG_REG_ADDR 0x2000604 +#define DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_PDSP0 0 +#define hwConfigStreamingSwitch() DEVICE_REG32_W(DEVICE_PSTREAM_CFG_REG_ADDR, DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_PDSP0); + + +/** + * @brief + * Register access macros + */ +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + +/** + * @brief + * Mpax configuration registers + */ +#define DEVICE_REG_XMPAX_L(x) *((volatile unsigned int *)(0x08000000 + (8*(x)))) +#define DEVICE_REG_XMPAX_H(x) *((volatile unsigned int *)(0x08000004 + (8*(x)))) + +#endif /* _TARGET_H */ diff --git a/src/device/device.h b/src/device/device.h index b03a553..952f328 100644 --- a/src/device/device.h +++ b/src/device/device.h @@ -150,3 +150,13 @@ bool deviceIsLittleEndian(void); #endif + +/** + * @brief + * Provide an approximate delay, in cpu cycles + * + * @details + * A delay loop + */ +void chipDelay32 (uint32 nCycles); + diff --git a/src/driver/eth/net.c b/src/driver/eth/net.c index fd1fecd..5147b0e 100644 --- a/src/driver/eth/net.c +++ b/src/driver/eth/net.c @@ -377,6 +377,9 @@ static Int32 net_open (void* ptr_driver, void (*asyncComplete)(void *)) */ static Int32 net_close (void) { + if (netmcb.net_device.stop) + (*netmcb.net_device.stop)(&netmcb.net_device); + return 0; } diff --git a/src/driver/eth/net.h b/src/driver/eth/net.h index e50ddd2..d066a4a 100644 --- a/src/driver/eth/net.h +++ b/src/driver/eth/net.h @@ -42,6 +42,8 @@ #ifndef __NET_H__ #define __NET_H__ +#include "iblloc.h" + /** * @brief This is the MAX MTU of the packet that can be received in * the network module. This is configured to Ethernet standards at 1518 diff --git a/src/ethboot/c64x/make/makefile b/src/ethboot/c64x/make/makefile index 2285422..871037f 100644 --- a/src/ethboot/c64x/make/makefile +++ b/src/ethboot/c64x/make/makefile @@ -65,6 +65,10 @@ C6X_C_DIR+= ;$(STDINC) C6X_C_DIR+= ;$(IBL_ROOT)/hw/macs C6X_C_DIR+= ;$(IBL_ROOT)/hw/mdio C6X_C_DIR+= ;$(IBL_ROOT)/hw/sgmii +C6X_C_DIR+= ;$(IBL_ROOT)/hw/cpsw +C6X_C_DIR+= ;$(IBL_ROOT)/hw/qm +C6X_C_DIR+= ;$(IBL_ROOT)/hw/cpdma +C6X_C_DIR+= ;$(IBL_ROOT)/hw/pa export C6X_C_DIR diff --git a/src/ethboot/ethboot.c b/src/ethboot/ethboot.c index fb78b7b..0388bf5 100644 --- a/src/ethboot/ethboot.c +++ b/src/ethboot/ethboot.c @@ -59,6 +59,9 @@ #include "mdioapi.h" #include #include "net_osal.h" +#include "cpsw_api.h" +#include "qm_api.h" +#include "cpdma_api.h" /** * @brief Remove the possible re-definition of iblEthBoot. iblcfg.h defines this to be a void @@ -113,7 +116,6 @@ void iblEthBoot (Int32 eIdx) char *ext; - /* Power up the device. No action is taken if the device is already powered up */ if (devicePowerPeriph (TARGET_PWR_ETH(ibl.ethConfig[eIdx].port)) < 0) return; @@ -126,9 +128,49 @@ void iblEthBoot (Int32 eIdx) /* SGMII configuration. If sgmii is not present this statement is defined * to void in target.h */ - hwSgmiiConfig (ibl.ethConfig[eIdx].port, &ibl.sgmiiConfig[eIdx]); + if (ibl.ethConfig[eIdx].port == ibl_PORT_SWITCH_ALL) { + for (n = 0; n < TARGET_EMAC_N_PORTS; n++) + hwSgmiiConfig (n, &ibl.sgmiiConfig[n]); + + } else { + + hwSgmiiConfig (ibl.ethConfig[eIdx].port, &ibl.sgmiiConfig[eIdx]); + } + + +#ifdef DEVICE_CPSW + /* On chip switch configuration */ + hwCpswConfig (targetGetSwitchCtl(), targetGetSwitchMaxPktSize()); +#endif + + +#ifdef DEVICE_QM + /* Queue manager configuration */ + hwQmSetup ((qmConfig_t *)(targetGetQmConfig())); + targetInitQs (); +#endif + + +#ifdef DEVICE_CPDMA + /* Cpdma configuration. */ + hwCpdmaRxConfig ((cpdmaRxCfg_t *)targetGetCpdmaRxConfig()); + hwCpdmaTxConfig ((cpdmaTxCfg_t *)targetGetCpdmaTxConfig()); +#endif + + +#ifdef DEVICE_PA + /* Packet accelerator configuration. If PA is not present this statement is defined + * to void in target.h */ + targetPaConfig(ibl.ethConfig[eIdx].ethInfo.hwAddress); +#endif +#ifdef DEVICE_SS + /* Streaming switch configuration. If not present this statement is defined to void + * in target.h. If present this is usually defined to a series of register writes */ + hwConfigStreamingSwitch(); +#endif + nDevice.port_num = ibl.ethConfig[eIdx].port; /* Simple transation to initialize the driver */ @@ -257,6 +299,24 @@ void iblEthBoot (Int32 eIdx) /* Close up the peripheral */ (*net_boot_module.close)(); + +#ifdef DEVICE_PA + hwPaDisable (); +#endif + +#ifdef DEVICE_CPDMA + /* Cpdma configuration. */ + hwCpdmaRxDisable ((cpdmaRxCfg_t *)targetGetCpdmaRxConfig()); + hwCpdmaTxDisable ((cpdmaTxCfg_t *)targetGetCpdmaTxConfig()); +#endif + +#ifdef DEVICE_QM + targetFreeQs (); + /* Queue manager configuration */ + hwQmTeardown (); +#endif + + if (entry != 0) { iblStatus.exitAddress = entry; diff --git a/src/hw/c64x/make/makefile b/src/hw/c64x/make/makefile index 7c58442..e6ed3f6 100644 --- a/src/hw/c64x/make/makefile +++ b/src/hw/c64x/make/makefile @@ -61,8 +61,14 @@ else else ifeq ($(TARGET),c6455) CSRC= t64.c cpmacdrv.c pll.c emif31.c mdio.c gpio.c nandgpio.c i2c.c nandwrgpio.c - else - CSRC= t64.c cpmacdrv.c pll.c psc.c emif31.c mdio.c gpio.c nandgpio.c i2c.c nandwrgpio.c sgmii.c + else + ifeq ($(TARGET),c661x) + CSRC= t64.c pll.c cfgpll.c cfgpll2.c mdio.c i2c.c psc.c cpsw.c qm.c cpdma.c pa.c sgmii.c serdes.c gmacsl.c emif4.c + CSRC+= nandemif25.c + else + CSRC= t64.c cpmacdrv.c pll.c psc.c emif31.c mdio.c gpio.c nandgpio.c i2c.c nandwrgpio.c sgmii.c cfgpll.c cfgpll2.c + CSRC+= qm.c cpdma.c pa.c serdes.c gmacsl.c emif4.c nandemif25.c + endif endif endif endif @@ -83,6 +89,8 @@ C6X_C_DIR+= ;$(STDINC) C6X_C_DIR+= ;$(IBL_ROOT)/cfg/$(TARGET) C6X_C_DIR+= ;$(IBL_ROOT)/hw/timer C6X_C_DIR+= ;$(IBL_ROOT)/hw/macs/cpmac +C6X_C_DIR+= ;$(IBL_ROOT)/hw/macs +C6X_C_DIR+= ;$(IBL_ROOT)/hw/macs/cpmacsl C6X_C_DIR+= ;$(IBL_ROOT)/driver/eth C6X_C_DIR+= ;$(IBL_ROOT)/device C6X_C_DIR+= ;$(IBL_ROOT)/device/$(TARGET) @@ -92,8 +100,12 @@ C6X_C_DIR+= ;$(IBL_ROOT)/hw/mdio C6X_C_DIR+= ;$(IBL_ROOT)/hw/gpio C6X_C_DIR+= ;$(IBL_ROOT)/hw/nands C6X_C_DIR+= ;$(IBL_ROOT)/hw/nands/gpio +C6X_C_DIR+= ;$(IBL_ROOT)/hw/nands/emif25 C6X_C_DIR+= ;$(IBL_ROOT)/hw/i2c C6X_C_DIR+= ;$(IBL_ROOT)/hw/sgmii +C6X_C_DIR+= ;$(IBL_ROOT)/hw/cpsw +C6X_C_DIR+= ;$(IBL_ROOT)/hw/cpdma +C6X_C_DIR+= ;$(IBL_ROOT)/hw/pa C6X_C_DIR+= ;$(IBL_ROOT)/ecc export C6X_C_DIR @@ -157,6 +169,22 @@ ifeq ($(TARGET),c6455) vpath % $(ECODIR)/i2c endif +ifeq ($(TARGET),c661x) + vpath % $(ECODIR)/plls/pll014phi + vpath % $(ECODIR)/mdio + vpath % $(ECODIR)/i2c + vpath % $(ECODIR)/pscs/psc2 + vpath % $(ECODIR)/cpsw + vpath % $(ECODIR)/qm + vpath % $(ECODIR)/cpdma + vpath % $(ECODIR)/pa + vpath % $(ECODIR)/sgmii + vpath % $(ECODIR)/serdes + vpath % $(ECODIR)/macs/cpmacsl + vpath % $(ECODIR)/ddrs/emif4 + vpath % $(ECODIR)/nands/emif25 +endif + hw: gen_cdefdep makefile $(OBJS) diff --git a/src/hw/c64x/make/makestg2 b/src/hw/c64x/make/makestg2 index 045bcd1..fa0d37b 100644 --- a/src/hw/c64x/make/makestg2 +++ b/src/hw/c64x/make/makestg2 @@ -8,7 +8,7 @@ #********************************************************************************* -DEVICES= c6455 c6472 c6474 c6474l c6457 +DEVICES= c6455 c6472 c6474 c6474l c6457 c661x ifndef IBL_ROOT IBL_ROOT=../.. diff --git a/src/hw/cpdma/cpdma.c b/src/hw/cpdma/cpdma.c new file mode 100644 index 0000000..651544f --- /dev/null +++ b/src/hw/cpdma/cpdma.c @@ -0,0 +1,191 @@ +/******************************************************************************************** + * FILE PURPOSE: The cpdma driver + ******************************************************************************************** + * FILE NAME: cpdma.c + * + * DESCRIPTION: The boot loader cpdma driver + * + ********************************************************************************************/ +#include "types.h" +#include "cpdma_loc.h" +#include "cpdma_api.h" +#include "device.h" + + +/********************************************************************************************* + * FUNCTION PURPOSE: Disable all rx channels and clear all the flow registers + ********************************************************************************************* + * DESCRIPTION: The teardown is initiated and polled for completion. The function will + * return an error if the teardown is never complete, but will not stay + * in the function forever. + *********************************************************************************************/ +SINT16 hwCpdmaRxDisable (const cpdmaRxCfg_t *cfg) +{ + UINT32 i; + UINT32 v; + BOOL done; + + for (i = 0; i < cfg->nRxChans; i++) { + + /* If enabled, set the teardown bit */ + v = DEVICE_REG32_R (cfg->rxBase + CPDMA_REG_RCHAN_CFG_REG_A(i)); + if ( (v & CPDMA_REG_VAL_RCHAN_A_RX_ENABLE) == CPDMA_REG_VAL_RCHAN_A_RX_ENABLE ) { + v = v | CPDMA_REG_VAL_RCHAN_A_RX_TDOWN; + DEVICE_REG32_W (cfg->rxBase + CPDMA_REG_RCHAN_CFG_REG_A(i), v); + } + + } + + /* Poll for completion */ + for (i = 0, done = FALSE; ( (i < cfg->tdownPollCount) && (done == FALSE) ); i++) { + + chipDelay32 (100); + + done = TRUE; + v = DEVICE_REG32_R (cfg->rxBase + CPDMA_REG_RCHAN_CFG_REG_A(i)); + if ( (v & CPDMA_REG_VAL_RCHAN_A_RX_ENABLE) == CPDMA_REG_VAL_RCHAN_A_RX_ENABLE ) + done = FALSE; + + } + + if (done == FALSE) + return (-1); + + + /* Clear all of the flow registers */ + for (i = 0; i < cfg->nRxFlows; i++) { + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_A, i), 0); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_B, i), 0); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_C, i), 0); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_D, i), 0); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_E, i), 0); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_F, i), 0); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_G, i), 0); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_H, i), 0); + + } + + return (0); + +} /* hwCpdmaRxDisable */ + + + +/********************************************************************************************* + * FUNCTION PURPOSE: Configure the cpdma receive direction for boot loader + ********************************************************************************************* + * DESCRIPTION: The receive configuration for boot consists of a single flow configuration + * which is stored as flow configuration 0. All extended info and psinfo + * is stripped. + *********************************************************************************************/ +SINT16 hwCpdmaRxConfig (const cpdmaRxCfg_t *cfg) +{ + UINT32 v; + UINT32 i; + SINT16 ret = 0; + + + /* Rx dma channels are disabled during flow configurations. + * Even if disable fails attempt to configure the receive so the boot can work */ + if (hwCpdmaRxDisable (cfg) != 0) + ret = -1; + + /* Configure the flow + * The flow is configured to not pass extended info or psinfo, with descriptor + * type host */ + + v = CPDMA_REG_VAL_MAKE_RX_FLOW_A( 1, /* extended info passed */ + 1, /* psinfo passed */ + 0, /* Retry on failure to transmit */ + CPDMA_DESC_TYPE_HOST, /* Host type descriptor */ + 0, /* PS located in descriptor */ + 0, /* SOP offset */ + cfg->qmNumRx, /* Rx packet destination QM number */ + cfg->queueRx ); /* Rx packet destination queue */ + + + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_A, 0), v); + + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_B, 0), CPDMA_REG_VAL_RX_FLOW_B_DEFAULT); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_C, 0), CPDMA_REG_VAL_RX_FLOW_C_DEFAULT); + + v = CPDMA_REG_VAL_MAKE_RX_FLOW_D ( cfg->qmNumFreeBuf, /* Rx packet destination QM number, 1st descriptor */ + cfg->queueFreeBuf, /* Rx packet destination queue, 1st descriptor */ + cfg->qmNumFreeBuf, /* Rx packet destination QM number, subsequent descriptors */ + cfg->queueFreeBuf ); /* Rx packet destination queue, subsequent descriptors */ + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_D, 0), v); + + + /* Register E uses the same setup as D */ + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_E, 0), v); + + + + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_F, 0), CPDMA_REG_VAL_RX_FLOW_F_DEFAULT); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_G, 0), CPDMA_REG_VAL_RX_FLOW_G_DEFAULT); + DEVICE_REG32_W (cfg->flowBase + CPDMA_RX_FLOW_CFG(CPDMA_RX_FLOW_REG_H, 0), CPDMA_REG_VAL_RX_FLOW_H_DEFAULT); + + + /* Enable the rx channels */ + for (i = 0; i < cfg->nRxChans; i++) + DEVICE_REG32_W (cfg->rxBase + CPDMA_REG_RCHAN_CFG_REG_A(i), CPDMA_REG_VAL_RCHAN_A_RX_ENABLE); + + + return (ret); + +} /* hwCpdmaRxConfig */ + + +/************************************************************************************************* + * FUNCTION PURPOSE: Configure the cpdma transmit direction for boot loader + ************************************************************************************************* + * DESCRIPTION: The transmit channels are enabled + *************************************************************************************************/ +SINT16 hwCpdmaTxConfig (const cpdmaTxCfg_t *cfg) +{ + UINT32 i; + + /* Disable loopback in the tx direction */ + DEVICE_REG32_W (cfg->gblCtlBase + CPDMA_REG_EMU_CTL, CPDMA_REG_VAL_EMU_CTL_NO_LOOPBACK); + + /* Enable all channels. The current state isn't important */ + for (i = 0; i < cfg->nTxChans; i++) { + DEVICE_REG32_W (cfg->txBase + CPDMA_REG_TCHAN_CFG_REG_B(i), 0); /* Priority */ + DEVICE_REG32_W (cfg->txBase + CPDMA_REG_TCHAN_CFG_REG_A(i), CPDMA_REG_VAL_TCHAN_A_TX_ENABLE); + } + + return (0); + +} /* hwCpdmaTxConfig */ + + +/*************************************************************************************************** + * FUNCTION PURPOSE: Disable the transmit channels + *************************************************************************************************** + * DESCRIPTION: The transmit channels are disabled + ***************************************************************************************************/ +SINT16 hwCpdmaTxDisable (const cpdmaTxCfg_t *cfg) +{ + UINT32 i; + UINT32 v; + + for (i = 0; i < cfg->nTxChans; i++) { + + v = DEVICE_REG32_R (cfg->txBase + CPDMA_REG_TCHAN_CFG_REG_A(i)); + + if ( (v & CPDMA_REG_VAL_TCHAN_A_TX_ENABLE) == CPDMA_REG_VAL_TCHAN_A_TX_ENABLE) { + v = v | CPDMA_REG_VAL_TCHAN_A_TX_TDOWN; + DEVICE_REG32_W (cfg->txBase + CPDMA_REG_TCHAN_CFG_REG_A(i), v); + } + } + + + return (0); + +} /* hwCpdmaTxDisable */ + + + + + + diff --git a/src/hw/cpdma/cpdma_api.h b/src/hw/cpdma/cpdma_api.h new file mode 100644 index 0000000..6149df6 --- /dev/null +++ b/src/hw/cpdma/cpdma_api.h @@ -0,0 +1,43 @@ +#ifndef _CPDMA_API_H +#define _CPDMA_API_H +/******************************************************************************************************** + * FILE PURPOSE: Provide the cpdma API + ******************************************************************************************************** + * FILE NAME: cpdma_api.h + * + * DESCRIPTION: The public API is defined + * + ********************************************************************************************************/ + + +typedef struct cpdmaRxCfg_s { + + UINT32 rxBase; /* Base address of rx registers */ + UINT32 nRxChans; /* The number of rx channels */ + UINT32 flowBase; /* Add address of flow registers */ + UINT32 nRxFlows; /* Number of rx flows */ + UINT32 qmNumFreeBuf; /* Queue manager for descriptors/buffers for received packets */ + UINT32 queueFreeBuf; /* Queue that holds descriptors/buffers for received packets */ + UINT32 qmNumRx; /* Queue manager for received packets */ + UINT32 queueRx; /* Default Rx queue for received packets */ + UINT32 tdownPollCount; /* Number of loop iterations to wait for teardown */ + +} cpdmaRxCfg_t; + + +typedef struct cpdmaTxCfg_s { + + UINT32 gblCtlBase; /* Base address of global control registers */ + UINT32 txBase; /* Base address of the tx registers */ + UINT32 nTxChans; /* The number of tx channels */ + +} cpdmaTxCfg_t; + + +/* Prototypes */ +SINT16 hwCpdmaRxDisable (const cpdmaRxCfg_t *cfg); +SINT16 hwCpdmaRxConfig (const cpdmaRxCfg_t *cfg); +SINT16 hwCpdmaTxConfig (const cpdmaTxCfg_t *cfg); +SINT16 hwCpdmaTxDisable (const cpdmaTxCfg_t *cfg); + +#endif /* _CPDMA_API_H */ diff --git a/src/hw/cpdma/cpdma_loc.h b/src/hw/cpdma/cpdma_loc.h new file mode 100644 index 0000000..93f2142 --- /dev/null +++ b/src/hw/cpdma/cpdma_loc.h @@ -0,0 +1,110 @@ +#ifndef _CPDMA_LOC_H +#define _CPDMA_LOC_H +/************************************************************************************************** + * FILE PURPOSE: Local description of the CPDMA + ************************************************************************************************** + * FILE NAME: cpdma_loc.h + * + * DESCRIPTION: Defines the layout of the cpdma peripheral + * + **************************************************************************************************/ + +/* Emulation control register */ +#define CPDMA_REG_EMU_CTL 0x08 + +/* CPPI Tx DMA channel control registers */ +#define CPDMA_REG_TCHAN_CFG_REG_A(x) (0x00 + (x)*0x20) +#define CPDMA_REG_TCHAN_CFG_REG_B(x) (0x04 + (x)*0x20) + + +/* CPPI Rx DMA channel control register */ +#define CPDMA_REG_RCHAN_CFG_REG_A(x) (0x00 + (x)*0x20) + +/* CPPI Tx DMA Scheduler Configuration register */ +#define CPDMA_REG_TCHAN_SCHED_CFG(x) ((x)*0x04) + +/* CPPI Rx DMA flow configuration registers */ +#define CPDMA_RX_FLOW_CFG(reg,idx) ( ((reg)*4) + ((idx)*0x20) ) +#define CPDMA_RX_FLOW_REG_A 0 +#define CPDMA_RX_FLOW_REG_B 1 +#define CPDMA_RX_FLOW_REG_C 2 +#define CPDMA_RX_FLOW_REG_D 3 +#define CPDMA_RX_FLOW_REG_E 4 +#define CPDMA_RX_FLOW_REG_F 5 +#define CPDMA_RX_FLOW_REG_G 6 +#define CPDMA_RX_FLOW_REG_H 7 + +/* Descriptor type created by flows */ +#define CPDMA_DESC_TYPE_HOST 1 + + +/* CPPI Tx DMA channel control register A definitions */ +#define CPDMA_REG_VAL_TCHAN_A_TX_ENABLE ((UINT32)1 << 31) +#define CPDMA_REG_VAL_TCHAN_A_TX_TDOWN (1 << 30) + +/* CPPI Tx DMA channel control register B definitions */ +#define CPDMA_REG_VAL_TCHAN_B_TX_FILT_EINFO (1 << 30) +#define CPDMA_REG_VAL_TCHAN_B_TX_FILT_PSWORDS (1 << 29) +#define CPDMA_REG_TCHAN_B_SET_DEFAULT_TDOWN_QMGR(x,v) (x) = (BOOT_SET_BITFIELD((x), (v), 13, 12) +#define CPDMA_REG_TCHAN_B_SET_DEFAULT_TDOWN_QNUM(x,v) (x) = (BOOT_SET_BITFIELD((x), (v), 11, 0) + + +/* CPPI Rx DMA channel control register A definitions */ +#define CPDMA_REG_VAL_RCHAN_A_RX_ENABLE ((UINT32)1 << 31) +#define CPDMA_REG_VAL_RCHAN_A_RX_TDOWN (1 << 30) + +/* CPPI Tx DMA Scheduler Confuration value. This sets the priorities of + * the channels. If set to all equal, the actual value doesn't matter */ +#define CPDMA_REG_VAL_TCHAN_SCHED_HIGH_PRIORITY 0 +#define CPDMA_REG_VAL_TCHAN_SCHED_MED_HIGH_PRIORITY 1 +#define CPDMA_REG_VAL_TCHAN_SCHED_MED_LOW_PRIORITY 2 +#define CPDMA_REG_VAL_TCHAN_SCHED_LOW_PRIORITY 3 + + +/* A very simply flow configuration is supported. No queue allocation by bins is supported */ + +/* CPPI Rx flow configuration register A */ +#define CPDMA_REG_VAL_MAKE_RX_FLOW_A(einfo,psinfo,rxerr,desc,psloc,sopOff,qmgr,qnum) \ + ( ((einfo & 1) << 30) | \ + ((psinfo & 1) << 29) | \ + ((rxerr & 1) << 28) | \ + ((desc & 3) << 26) | \ + ((psloc & 1) << 25) | \ + ((sopOff & 0x1ff) << 16) | \ + ((qmgr & 3) << 12) | \ + ((qnum & 0xfff) << 0) ) + +/* CPPI Rx flow configuration register B. No tags are used */ +#define CPDMA_REG_VAL_RX_FLOW_B_DEFAULT 0 + + +/* CPPI Rx flow configuration register C. No tag replacement and no size thresholds */ +#define CPDMA_REG_VAL_RX_FLOW_C_DEFAULT 0 + +/* CPPI Rx flow configuration register D */ +#define CPDMA_REG_VAL_MAKE_RX_FLOW_D(fd0Qm, fd0Qnum, fd1Qm, fd1Qnum) \ + ( ((fd0Qm & 3) << 28) | \ + ((fd0Qnum & 0xfff) << 16) | \ + ((fd1Qm & 3) << 12) | \ + ((fd1Qnum & 0xfff) << 0) ) + +/* CPPI Rx flow configuration register E */ +#define CPDMA_REG_VAL_RX_FLOW_E_DEFAULT 0 + +/* CPPI Rx flow configuration register F */ +#define CPDMA_REG_VAL_RX_FLOW_F_DEFAULT 0 + +/* CPPI Rx flow configuration register G */ +#define CPDMA_REG_VAL_RX_FLOW_G_DEFAULT 0 + +/* CPPI Rx flow configuration register H */ +#define CPDMA_REG_VAL_RX_FLOW_H_DEFAULT 0 + +/* Default Emulation control register value disables loopback */ +#define CPDMA_REG_VAL_EMU_CTL_NO_LOOPBACK 0 + + +#endif /* _CPDMA_LOC_H */ + + + diff --git a/src/hw/cpsw/cpsw.c b/src/hw/cpsw/cpsw.c new file mode 100644 index 0000000..c02534c --- /dev/null +++ b/src/hw/cpsw/cpsw.c @@ -0,0 +1,50 @@ +/*********************************************************************************************** + * FILE PURPOSE: Configure the cpsw + *********************************************************************************************** + * FILE NAME: cpsw.c + * + * DESCRIPTION: The common platform ethernet switch driver + * + ************************************************************************************************/ +#include "types.h" +#include "cpsw_loc.h" +#include "cpsw_api.h" +#include "device.h" + + + +/************************************************************************************************ + * FUNCTION PURPOSE: Configure the switch + ************************************************************************************************ + * DESCRIPTION: The switch is setup without respect to its current state. The ALE + * is reset during the configuration. + ************************************************************************************************/ +SINT16 hwCpswConfig (UINT32 ctl, UINT32 maxPktSize) +{ + UINT32 i; + + /* Max length register */ + DEVICE_REG32_W (DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, maxPktSize); + + /* Control register */ + DEVICE_REG32_W (DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl); + + /* All statistics enabled by default */ + DEVICE_REG32_W (DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN, CPSW_REG_VAL_STAT_ENABLE_ALL); + + /* Reset and enable the ALE */ + DEVICE_REG32_W (DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL, CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE); + + /* All ports put into forward mode */ + for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++) + DEVICE_REG32_W (DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i), CPSW_REG_VAL_PORTCTL_FORWARD_MODE); + + + return (0); + +} /* hwCpswConfig */ + + + + + diff --git a/src/hw/cpsw/cpsw_api.h b/src/hw/cpsw/cpsw_api.h new file mode 100644 index 0000000..811a43f --- /dev/null +++ b/src/hw/cpsw/cpsw_api.h @@ -0,0 +1,30 @@ +#ifndef _CPSW_API_H +#define _CPSW_API_H +/************************************************************************************************* + * FILE PURPOSE: Common Platform ethernet SWitch driver API + ************************************************************************************************* + * FILE NAME: cpsw_api.h + * + * DESCRIPTION: Defines the driver interface for the switch + * + *************************************************************************************************/ + +/* Control bitfields */ +#define CPSW_CTL_P2_PASS_PRI_TAGGED (1 << 5) +#define CPSW_CTL_P1_PASS_PRI_TAGGED (1 << 4) +#define CPSW_CTL_P0_PASS_PRI_TAGGED (1 << 3) +#define CPSW_CTL_P0_ENABLE (1 << 2) +#define CPSW_CTL_VLAN_AWARE (1 << 1) +#define CPSW_CTL_FIFO_LOOPBACK (1 << 0) + +/* API */ +SINT16 hwCpswConfig (UINT32 ctl, UINT32 maxPktSize); +SINT16 hwCpswEnableP0 (void); +BOOL hwCpswIsEnabled (void); + + + + + +#endif /* _CPSW_API_H */ + diff --git a/src/hw/cpsw/cpsw_loc.h b/src/hw/cpsw/cpsw_loc.h new file mode 100644 index 0000000..d4b4dfb --- /dev/null +++ b/src/hw/cpsw/cpsw_loc.h @@ -0,0 +1,26 @@ +#ifndef _CPSW_LOC_H +#define _CPSW_LOC_H +/********************************************************************************************** + * FILE PURPOSE: Local definitions for the Common Platform Ethernet Switch + ********************************************************************************************** + * FILE NAME: cpsw_loc.h + * + * DESCRIPTION: Defines the peripheral registers used to configure the switch + * + **********************************************************************************************/ + +/* Register offsets */ +#define CPSW_REG_CTL 0x004 +#define CPSW_REG_STAT_PORT_EN 0x00c +#define CPSW_REG_MAXLEN 0x040 +#define CPSW_REG_ALE_CONTROL 0x608 +#define CPSW_REG_ALE_PORTCTL(x) (0x640 + (x)*4) + + +/* Register values */ +#define CPSW_REG_VAL_STAT_ENABLE_ALL 0xf +#define CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE ((UINT32)0xc0000000) +#define CPSW_REG_VAL_PORTCTL_FORWARD_MODE 0x3 + + +#endif /* _CPSW_LOC_H */ diff --git a/src/hw/ddrs/emif4/emif4.c b/src/hw/ddrs/emif4/emif4.c new file mode 100644 index 0000000..7f2415a --- /dev/null +++ b/src/hw/ddrs/emif4/emif4.c @@ -0,0 +1,115 @@ +/************************************************************************************************* + * FILE PURPOSE: EMIF4 driver + ************************************************************************************************* + * FILE NAME: emif4.c + * + * DESCRIPTION: The boot emif4 driver + * + *************************************************************************************************/ +#include "types.h" +#include "ibl.h" +#include "emif4_api.h" +#include "emif4_loc.h" +#include "device.h" + +/************************************************************************************************* + * FUNCTION PUROPSE: Initial EMIF4 setup + ************************************************************************************************* + * DESCRIPTION: Emif configuration + *************************************************************************************************/ +SINT16 hwEmif4p0Enable (iblEmif4p0_t *cfg) +{ + UINT32 v; + + /* If the config registers or refresh control registers are being written + * disable the initialization sequence until they are all setup */ + if ((cfg->registerMask & EMIF4_INIT_SEQ_MASK) != 0) { + + v = DEVICE_REG32_R (DEVICE_EMIF4_BASE + EMIF_REG_SDRAM_REF_CTL); + EMIF_REG_VAL_SDRAM_REF_CTL_SET_INITREF_DIS(v,1); + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_SDRAM_REF_CTL, v); + } + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_sdRamTiming1) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_TIMING1, cfg->sdRamTiming1); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_sdRamTiming2) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_TIMING2, cfg->sdRamTiming2); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_sdRamTiming3) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_TIMING3, cfg->sdRamTiming3); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_lpDdrNvmTiming) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_NVM_TIMING, cfg->lpDdrNvmTiming); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_powerManageCtl) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_PWR_MNG_CTL, cfg->powerManageCtl); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_iODFTTestLogic) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_IODFT_TST_LOGIC, cfg->iODFTTestLogic); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_performCountCfg) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_PERFORM_CNT_CFG, cfg->performCountCfg); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_performCountMstRegSel) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_PERFORM_CNT_MST_REG_SEL, cfg->performCountMstRegSel); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_readIdleCtl) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_IDLE_CTL, cfg->readIdleCtl); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_sysVbusmIntEnSet) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_INT_EN_SET, cfg->sysVbusmIntEnSet); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_sdRamOutImpdedCalCfg) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_OUT_IMP_CAL_CFG, cfg->sdRamOutImpdedCalCfg); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_tempAlterCfg) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_TEMP_ALTER_CFG, cfg->tempAlterCfg); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_ddrPhyCtl1) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_PHY_CTL1, cfg->ddrPhyCtl1); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_ddrPhyCtl2) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_PHY_CLT2, cfg->ddrPhyCtl2); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_priClassSvceMap) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_PRI_CLASS_SVC_MAP, cfg->priClassSvceMap); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_mstId2ClsSvce1Map) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_ID2CLS_SVC_1MAP, cfg->mstId2ClsSvce1Map); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_mstId2ClsSvce2Map) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_ID2CLS_SVC_2MAP, cfg->mstId2ClsSvce2Map); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_eccCtl) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_ECC_CTL, cfg->eccCtl); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_eccRange1) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_ECC_RANGE1, cfg->eccRange1); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_eccRange2) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_ECC_RANGE2, cfg->eccRange2); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_rdWrtExcThresh) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_RD_WRT_EXC_THRESH, cfg->rdWrtExcThresh); + + /* Allow the configuration to occur */ + v = DEVICE_REG32_R (DEVICE_EMIF4_BASE + EMIF_REG_SDRAM_REF_CTL); + EMIF_REG_VAL_SDRAM_REF_CTL_SET_INITREF_DIS(v,0); + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_SDRAM_REF_CTL, v); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_sdRamConfig) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_SD_RAM_CFG, cfg->sdRamConfig); + + if ((cfg->registerMask & ibl_EMIF4_ENABLE_sdRamConfig2) != 0) + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_SD_RAM_CFG2, cfg->sdRamConfig2); + + v = cfg->sdRamRefreshCtl; + EMIF_REG_VAL_SDRAM_REF_CTL_SET_INITREF_DIS(v,0); + DEVICE_REG32_W (DEVICE_EMIF4_BASE + EMIF_REG_SDRAM_REF_CTL, v); + + return (0); + +} /* hwEmif4p0Enable */ + + diff --git a/src/hw/ddrs/emif4/emif4_api.h b/src/hw/ddrs/emif4/emif4_api.h new file mode 100644 index 0000000..f449344 --- /dev/null +++ b/src/hw/ddrs/emif4/emif4_api.h @@ -0,0 +1,22 @@ +#ifndef _EMIF4_API_H +#define _EMIF4_API_H +/********************************************************************************************** + * FILE PURPOSE: Define the boot driver emif4 API + ********************************************************************************************** + * FILE NAME: emif4_api.h + * + * DESCRIPTION: The emif4 driver is defined + * + **********************************************************************************************/ +#include "types.h" +#include "ibl.h" + + +SINT16 hwEmif4p0Enable (iblEmif4p0_t *cfg); + + + + + +#endif /* EMIF4_API_H */ + diff --git a/src/hw/ddrs/emif4/emif4_loc.h b/src/hw/ddrs/emif4/emif4_loc.h new file mode 100644 index 0000000..119a9be --- /dev/null +++ b/src/hw/ddrs/emif4/emif4_loc.h @@ -0,0 +1,52 @@ +#ifndef _EMIF4_LOC_H +#define _EMIF4_LOC_H +/************************************************************************************************ + * FILE PURPOSE: EMIF4 peripheral definitions + ************************************************************************************************ + * FILE NAME: emif4_loc.h + * + * DESCRIPTION: Local definitions for the emif4 driver + * + ************************************************************************************************/ +#include "types.h" + + +#define EMIF4_INIT_SEQ_MASK ibl_EMIF4_ENABLE_sdRamConfig | \ + ibl_EMIF4_ENABLE_sdRamConfig2 | \ + ibl_EMIF4_ENABLE_sdRamRefreshCtl + +/* Register offsets */ +#define EMIF_REG_SD_RAM_CFG 0x008 +#define EMIF_REG_SD_RAM_CFG2 0x00c +#define EMIF_REG_SDRAM_REF_CTL 0x010 +#define EMIF_REG_TIMING1 0x018 +#define EMIF_REG_TIMING2 0x020 +#define EMIF_REG_TIMING3 0x028 +#define EMIF_REG_NVM_TIMING 0x030 +#define EMIF_REG_PWR_MNG_CTL 0x038 +#define EMIF_REG_IODFT_TST_LOGIC 0x060 +#define EMIF_REG_PERFORM_CNT_CFG 0x080 +#define EMIF_REG_PERFORM_CNT_MST_REG_SEL 0x08c +#define EMIF_REG_IDLE_CTL 0x098 +#define EMIF_REG_INT_EN_SET 0x0b4 +#define EMIF_REG_OUT_IMP_CAL_CFG 0x0c8 +#define EMIF_REG_TEMP_ALTER_CFG 0x0cc +#define EMIF_REG_PHY_CTL1 0x0e4 +#define EMIF_REG_PHY_CLT2 0x0ec +#define EMIF_REG_PRI_CLASS_SVC_MAP 0x100 +#define EMIF_REG_ID2CLS_SVC_1MAP 0x104 +#define EMIF_REG_ID2CLS_SVC_2MAP 0x108 +#define EMIF_REG_ECC_CTL 0x110 +#define EMIF_REG_ECC_RANGE1 0x114 +#define EMIF_REG_ECC_RANGE2 0x118 +#define EMIF_REG_RD_WRT_EXC_THRESH 0x120 + +#define EMIF_REG_VAL_SDRAM_REF_CTL_SET_INITREF_DIS(x,v) (x) = BOOT_SET_BITFIELD((x),(v),31,31) +#define EMIF_REG_VAL_SDRAM_REF_CTL_SET_SELF_REFRESH(x,v) (x) = BOOT_SET_BITFIELD((x),(v),28,28) + + +#endif /* _EMIF4_LOC_H */ + + + + diff --git a/src/hw/macs/cpmacsl/gmacsl.c b/src/hw/macs/cpmacsl/gmacsl.c new file mode 100644 index 0000000..d8fd20e --- /dev/null +++ b/src/hw/macs/cpmacsl/gmacsl.c @@ -0,0 +1,140 @@ +/****************************************************************************************** + * FILE PURPOSE: Mac sliver driver + ****************************************************************************************** + * FILE NAME: gmacsl.c + * + * DESCRIPTION: The cpgmac sliver driver + ******************************************************************************************/ +#include "types.h" +#include "cpmacdrv.h" +#include "gmacsl_loc.h" +#include "gmacsl_api.h" +#include "ibl.h" +#include "iblcfg.h" +#include "iblloc.h" +#include "device.h" + + +/******************************************************************************************** + * FUNCTION PURPOSE: Reset the the gmac sliver + ******************************************************************************************** + * DESCRIPTION: Soft reset is set and polled until clear, or until a timeout occurs + ********************************************************************************************/ +SINT16 hwGmacSlReset (UINT16 port) +{ + UINT32 i; + UINT32 v; + + if (port >= DEVICE_N_GMACSL_PORTS) + return (GMACSL_RET_INVALID_PORT); + + /* Set the soft reset bit */ + DEVICE_REG32_W (DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET); + + /* Wait for the bit to clear */ + for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { + + v = DEVICE_REG32_R (DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); + if ( (v & CPGMAC_REG_RESET_VAL_RESET_MASK) != CPGMAC_REG_RESET_VAL_RESET) + return (GMACSL_RET_OK); + + } + + /* Timeout on the reset */ + return (GMACSL_RET_WARN_RESET_INCOMPLETE); + +} /* hwGmacSlReset */ + + +/******************************************************************************************* + * FUNCTION PURPOSE: Configure the gmac sliver + ******************************************************************************************* + * DESCRIPTION: The emac sliver is configured. + *******************************************************************************************/ +SINT16 hwGmacSlConfig (UINT16 port, hwGmacSlCfg_t *cfg) +{ + UINT32 v; + UINT32 i; + SINT16 ret = GMACSL_RET_OK; + + + if (port >= DEVICE_N_GMACSL_PORTS) + return (GMACSL_RET_INVALID_PORT); + + if (cfg->maxRxLen > CPGMAC_REG_MAXLEN_LEN) { + cfg->maxRxLen = CPGMAC_REG_MAXLEN_LEN; + ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; + } + + /* Must wait if the device is undergoing reset */ + for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { + + v = DEVICE_REG32_R (DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); + if ( (v & CPGMAC_REG_RESET_VAL_RESET_MASK) != CPGMAC_REG_RESET_VAL_RESET) + break; + + } + + if (i == DEVICE_EMACSL_RESET_POLL_COUNT) + return (GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE); + + + + + DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN, cfg->maxRxLen); + + DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL, cfg->ctl); + + return (ret); + +} /* hwGmacSlConfig */ + + + +Int32 cpmac_drv_start (NET_DRV_DEVICE* ptr_device) +{ + Int32 i; + hwGmacSlCfg_t cfg; + + + cfg.maxRxLen = MAX_SIZE_STREAM_BUFFER; + cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; + + if (ptr_device->port_num == ibl_PORT_SWITCH_ALL) { + + for (i = 0; i < TARGET_EMAC_N_PORTS; i++) { + hwGmacSlReset (i); + hwGmacSlConfig (i, &cfg); + } + + } else { + + hwGmacSlReset (ptr_device->port_num); + hwGmacSlConfig (ptr_device->port_num, &cfg); + + } + + return (0); + +} + +Int32 cpmac_drv_send (NET_DRV_DEVICE* ptr_device, Uint8* buffer, int num_bytes) +{ + return (targetMacSend ((void *)ptr_device, buffer, num_bytes)); +} + + + +Int32 cpmac_drv_receive (NET_DRV_DEVICE* ptr_device, Uint8* buffer) +{ + return (targetMacRcv ((void *)ptr_device, buffer)); + +} + + +Int32 cpmac_drv_stop (NET_DRV_DEVICE* ptr_device) +{ + + hwGmacSlReset (ptr_device->port_num); + return (0); +} diff --git a/src/hw/macs/cpmacsl/gmacsl_api.h b/src/hw/macs/cpmacsl/gmacsl_api.h new file mode 100644 index 0000000..0e09ad4 --- /dev/null +++ b/src/hw/macs/cpmacsl/gmacsl_api.h @@ -0,0 +1,64 @@ +#ifndef _GMACSL_API_H +#define _GMACSL_API_H +/******************************************************************************************* + * FILE PURPOSE: Mac sliver API + ******************************************************************************************* + * FILE NAME: gmacsl_api.h + * + * DESCRIPTION: Defines the API for control of the CPGMAC sliver + * + *******************************************************************************************/ + +/******************************************************************************************* + * Definition: The cpgmac sliver configuration structure + *******************************************************************************************/ +typedef struct hwGmacSlCfg_s { + + UINT32 maxRxLen; /* Maximum receive packet length. */ + + UINT32 ctl; /* Control bitfield */ + +} hwGmacSlCfg_t; + + +/******************************************************************************************* + * Definition: Control bitfields used in the ctl field of hwGmacSlCfg_t + *******************************************************************************************/ +#define GMACSL_RX_ENABLE_RCV_CONTROL_FRAMES (1 << 24) +#define GMACSL_RX_ENABLE_RCV_SHORT_FRAMES (1 << 23) +#define GMACSL_RX_ENABLE_RCV_ERROR_FRAMES (1 << 22) +#define GMACSL_RX_ENABLE_EXT_CTL (1 << 18) /* duplex and gig read from input pins */ +#define GMACSL_RX_ENABLE_GIG_FORCE (1 << 17) +#define GMACSL_RX_ENABLE_IFCTL_B (1 << 16) +#define GMACSL_RX_ENABLE_IFCTL_A (1 << 15) +#define GMACSL_RX_ENABLE_CMD_IDLE (1 << 11) +#define GMACSL_TX_ENABLE_SHORT_GAP (1 << 10) +#define GMACSL_ENABLE_GIG_MODE (1 << 7) +#define GMACSL_TX_ENABLE_PACE (1 << 6) +#define GMACSL_ENABLE (1 << 5) +#define GMACSL_TX_ENABLE_FLOW_CTL (1 << 4) +#define GMACSL_RX_ENABLE_FLOW_CTL (1 << 3) +#define GMACSL_ENABLE_LOOPBACK (1 << 1) +#define GMACSL_ENABLE_FULL_DUPLEX (1 << 0) + + +/******************************************************************************************** + * DEFINTITION: function return values + ********************************************************************************************/ +#define GMACSL_RET_OK 0 +#define GMACSL_RET_INVALID_PORT -1 +#define GMACSL_RET_WARN_RESET_INCOMPLETE -2 +#define GMACSL_RET_WARN_MAXLEN_TOO_BIG -3 +#define GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE -4 + + +SINT16 hwGmacSlReset (UINT16 port); +SINT16 hwGmacSlConfig (UINT16 port, hwGmacSlCfg_t *cfg); + + + + + +#endif /* _GMACSL_API_H */ + + diff --git a/src/hw/macs/cpmacsl/gmacsl_loc.h b/src/hw/macs/cpmacsl/gmacsl_loc.h new file mode 100644 index 0000000..9fef685 --- /dev/null +++ b/src/hw/macs/cpmacsl/gmacsl_loc.h @@ -0,0 +1,36 @@ +#ifndef _GMACSL_LOC_H +#define _GMACSL_LOC_H +/***************************************************************************************** + * FILE PURPOSE: Local definitions for the cpgmac sliver + ***************************************************************************************** + * FILE NAME: gmacsl_loc.h + * + * DESCRIPTION: Defines the peripheral registers used to configure the cpgmac sliver + * + ******************************************************************************************/ + +/* Register offsets */ +#define CPGMACSL_REG_ID 0x00 +#define CPGMACSL_REG_CTL 0x04 +#define CPGMACSL_REG_STATUS 0x08 +#define CPGMACSL_REG_RESET 0x0c +#define CPGMACSL_REG_MAXLEN 0x10 +#define CPGMACSL_REG_BOFF 0x14 +#define CPGMACSL_REG_RX_PAUSE 0x18 +#define CPGMACSL_REG_TX_PAURSE 0x1c +#define CPGMACSL_REG_EM_CTL 0x20 +#define CPGMACSL_REG_PRI 0x24 + + +/* Soft reset register values */ +#define CPGMAC_REG_RESET_VAL_RESET_MASK (1 << 0) +#define CPGMAC_REG_RESET_VAL_RESET (1 << 0) + +/* Maxlen register values */ +#define CPGMAC_REG_MAXLEN_LEN 0x3fff + + + + +#endif /* _GMACSL_LOC_H */ + diff --git a/src/hw/nands/emif25/nandemif25.c b/src/hw/nands/emif25/nandemif25.c new file mode 100644 index 0000000..3801a15 --- /dev/null +++ b/src/hw/nands/emif25/nandemif25.c @@ -0,0 +1,201 @@ +/* + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * 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 Texas Instruments Incorporated 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 IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +#include "types.h" +#include "ibl.h" +#include "iblcfg.h" +#include "nandhwapi.h" +#include "nandemif25_loc.h" +#include "ecc.h" +#include "target.h" + +int32 gCs; /* The chip select space */ +uint32 memBase; /* Base address in device memory map */ +nandDevInfo_t *hwDevInfo; /* Pointer to the device configuraiton */ + +/** + * @brief + * Initialize the Nand emif interface + */ +Int32 nandHwDriverInit (int32 cs, nandDevInfo_t *devInfo) +{ + /* Bound check the chip select */ + if ((cs < 2) || (cs > 5)) + return (NAND_INVALID_CS); + + /* Check the bus width */ + if ((hwDevInfo->busWidthBits != 8) && (hwDevInfo->busWidthBits != 16)) + return (NAND_INVALID_ADDR_SIZE); + + gCs = cs; + hwDevInfo = devInfo; + + memBase = deviceNandMemBase (cs); + + /* Enable NAND on the specified chip select, all other bits set to 0 */ + DEVICE_REG32_W (DEVICE_EMIF25_BASE + NAND_FLASH_CTL_REG, (1 << (cs - 2))); + + return (0); + +} + +/** + * @brief + * Read bytes without ecc correction + */ + +Int32 nandHwDriverReadBytes (Uint32 block, Uint32 page, Uint32 byte, Uint32 nbytes, Uint8 *data) +{ + Int32 i; + Uint32 uAddr; + Uint8 *v8Addr; + Uint16 *v16Addr; + Uint16 *vData; + + /* Form the base address */ + uAddr = memBase + (block << hwDevInfo->blockOffset) + (page << hwDevInfo->pageOffset) + + (byte << hwDevInfo->columnOffset); + + if (hwDevInfo->busWidthBits == 8) { + + v8Addr = (Uint8 *)uAddr; + for (i = 0; i < nbytes; i++) + data[i] = v8Addr[i]; + + } else { + + v16Addr = (Uint16 *)uAddr; + vData = (Uint16 *)data; + + for (i = 0; i < (nbytes+1) >> 1; i++) + vData[i] = v16Addr[i]; + + } + + return (0); + +} + +/** + * @brief + * Convert the 32 bit ecc format used by the emif25 into the 3 byte values used by the software + * ecc algorithm + */ +void nand_format_ecc (uint32 v32, Uint8 *v8) +{ + /* An intrinsic is used for devices that support the shfl instruction */ + v32 = TARGET_SHFL(v32); + + v8[0] = (v32 >> 0) & 0xff; + v8[1] = (v32 >> 8) & 0xff; + v8[1] = (v32 >> 16) & 0x3f; /* p2048o and p2048e are unused and must be masked out */ + +} + +/** + * @brief + * Read a complete page of data + */ +Int32 nandHwDriverReadPage (Uint32 block, Uint32 page, Uint8 *data) +{ + Int32 i; + Int32 nSegs; + Uint32 v; + Uint8 *blockp; + Uint32 eccv; + Uint8 eccHw[3]; + Uint8 eccFlash[3]; + + /* Break the page into segments of 256 bytes, each with its own ECC */ + nSegs = hwDevInfo->pageSizeBytes >> 8; + + for (i = 0; i < nSegs; i++) { + + blockp = &data[i << 8]; + + + /* Read the ecc bytes stored in the extra page data */ + nandHwDriverReadBytes (block, page, hwDevInfo->pageSizeBytes + hwDevInfo->pageEccBytes - ((nSegs - i) * 4), 4, (Uint8 *)eccv); + + + /* Reset the hardware ECC correction by reading the ECC status register */ + v = DEVICE_REG32_R (DEVICE_EMIF25_BASE + NAND_FLASH_ECC_REG(gCs)); + + /* Enable ECC */ + v = DEVICE_REG32_R (DEVICE_EMIF25_BASE + NAND_FLASH_CTL_REG); + v = v | (1 << (gCs + 8 - 2)); + DEVICE_REG32_W (DEVICE_EMIF25_BASE + NAND_FLASH_CTL_REG, v); + + nandHwDriverReadBytes (block, page, i << 8, 256, data); + + /* Read the ECC value computed by the hardware */ + v = DEVICE_REG32_R (DEVICE_EMIF25_BASE + NAND_FLASH_ECC_REG(gCs)); + + /* Format the ecc values to match what the software is looking for */ + nand_format_ecc (eccv, eccFlash); + nand_format_ecc (v, eccHw); + + if (eccCorrectData (blockp, eccFlash, eccHw)) + return (NAND_ECC_FAILURE); + + } + + return (0); + +} + + + +/** + * @brief + * Close the low level driver + */ +Int32 nandHwDriverClose (void) +{ + int32 v; + + /* Simply read the ECC to clear the ECC calculation */ + v = DEVICE_REG32_R (DEVICE_EMIF25_BASE + NAND_FLASH_ECC_REG(gCs)); + + return (0); + +} + + + + + + + diff --git a/src/hw/nands/emif25/nandemif25_loc.h b/src/hw/nands/emif25/nandemif25_loc.h new file mode 100644 index 0000000..b268241 --- /dev/null +++ b/src/hw/nands/emif25/nandemif25_loc.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * 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 Texas Instruments Incorporated 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 IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +#ifndef _NAND_EMIF25_LOC_H +#define _NAND_EMIF25_LOC_H + +/* Register offsets */ +#define NAND_FLASH_CTL_REG 0x60 +#define NAND_FLASH_ECC_REG(x) (0xc0 + (((x)-2)*4)) + + +#endif /* _NAND_EMIF25_LOCK_H */ diff --git a/src/hw/nands/gpio/nandgpio.c b/src/hw/nands/gpio/nandgpio.c index 2104a44..f5acad6 100644 --- a/src/hw/nands/gpio/nandgpio.c +++ b/src/hw/nands/gpio/nandgpio.c @@ -159,7 +159,7 @@ void ptNandConfig (void) * @brief Initialize the driver * */ -Int32 nandHwDriverInit (nandDevInfo_t *devInfo) +Int32 nandHwDriverInit (int32 cs, nandDevInfo_t *devInfo) { Uint32 cmd; diff --git a/src/hw/nands/nandhwapi.h b/src/hw/nands/nandhwapi.h index 9884dea..8042dc9 100644 --- a/src/hw/nands/nandhwapi.h +++ b/src/hw/nands/nandhwapi.h @@ -56,6 +56,7 @@ #define NAND_NULL_ARG -811 #define NAND_INVALID_ADDR -812 #define NAND_ECC_FAILURE -813 +#define NAND_INVALID_CS -814 /* Information used only for programming flash */ @@ -76,7 +77,7 @@ typedef struct nandProgramInfo_s /* Driver functions */ -Int32 nandHwDriverInit (nandDevInfo_t *devInfo); +Int32 nandHwDriverInit (int32 cs, nandDevInfo_t *devInfo); Int32 nandHwDriverReadBytes (Uint32 block, Uint32 page, Uint32 byte, Uint32 nbytes, Uint8 *data); Int32 nandHwDriverReadPage(Uint32 block, Uint32 page, Uint8 *data); Int32 nandHwDriverClose (void); diff --git a/src/hw/pa/hwpafw_bin.h b/src/hw/pa/hwpafw_bin.h new file mode 100644 index 0000000..c4a1ef9 --- /dev/null +++ b/src/hw/pa/hwpafw_bin.h @@ -0,0 +1,65 @@ + + +/* This file contains the PDSP instructions in a C array which are to */ +/* be downloaded from the host CPU to the PDSP instruction memory. */ +/* This file is generated by the PDSP assembler. */ + +const unsigned int PDSPcode[] = { + 0x2eff9196, + 0x85002096, + 0x0101f6f6, + 0x81002496, + 0xcf04fffe, + 0x2e808f86, + 0x240cecc2, + 0x2411e082, + 0x68e2ec05, + 0x59108926, + 0x24002104, + 0x2f000384, + 0x21000200, + 0x0101f7f7, + 0x81042497, + 0x24000c04, + 0x2f000384, + 0x2e808f86, + 0x24000004, + 0x240020c4, + 0x2f000384, + 0x2e808f8e, + 0x68e6fb04, + 0x68c7dc03, + 0x0101f8f8, + 0x21002400, + 0x68e6fd04, + 0x68c7de03, + 0x0101f9f9, + 0x21002400, + 0x0101fafa, + 0x810c249a, + 0x24002104, + 0x2f000384, + 0x8700e286, + 0x21000200, + 0x00f9f8e1, + 0x81082481, + 0x24002004, + 0x24000644, + 0x24000064, + 0x109e9ec5, + 0x2400b024, + 0x24000005, + 0x2f000384, + 0x8700e186, + 0x21000200, + 0x24000c04, + 0x2f000384, + 0x2e80878e, + 0x10eeeefb, + 0x10efeffc, + 0x10f0f0fd, + 0x10f1f1fe, + 0x24002104, + 0x2f000384, + 0x21000200 }; + diff --git a/src/hw/pa/hwpafwsw.h b/src/hw/pa/hwpafwsw.h new file mode 100644 index 0000000..f413bc4 --- /dev/null +++ b/src/hw/pa/hwpafwsw.h @@ -0,0 +1,22 @@ +#ifndef _HWPAFWSW_H +#define _HWPAFWSW_H + +#ifdef _GIBERISH___ + **************************************************************************************** + * FILE PURPOSE: Definitions common between PA firmware and GEM software + **************************************************************************************** + * FILE NAME: hwpafwsw.h + * + * DESCRIPTION: Contains definitions used by both the PA firmware and GEM software + **************************************************************************************** +#endif + +#define PA_MAGIC_ID 0x0CEC11E0 + +#endif + + + + + + diff --git a/src/hw/pa/pa.c b/src/hw/pa/pa.c new file mode 100644 index 0000000..2ff2ec6 --- /dev/null +++ b/src/hw/pa/pa.c @@ -0,0 +1,124 @@ +/**************************************************************************************************** + * FILE PURPOSE: The boot loader packet accelerator driver + **************************************************************************************************** + * FILE NAME: pa.c + * + * DESCRIPTION: The driver for the packet accelerator during boot + * + ****************************************************************************************************/ +#include "types.h" +#include "pa_loc.h" +#include "pa_api.h" +#include "device.h" +#include "hwpafw_bin.h" +#include + +/**************************************************************************************************** + * FUNCTION PURPOSE: Initialize the PA sub-system + **************************************************************************************************** + * DESCRIPTION: Only PDSP 0 is used. All other PDSPs are put into reset. PDSP0 is downloaded + * and started, then provided with the mac address configuration. + ****************************************************************************************************/ +SINT16 hwPaEnable (const paConfig_t *cfg) +{ + UINT32 i; + UINT32 v; + BOOL done; + + /* Disable all PDSPs */ + for (i = 0; i < DEVICE_PA_NUM_PDSPS; i++) + DEVICE_REG32_W (DEVICE_PA_BASE + PA_REG_PDSP_CTL(i), PA_REG_VAL_PDSP_CTL_DISABLE_PDSP); + + /* Clear the mailbox registers for PDSP 0 */ + for (i = 0; i < PA_NUM_MAILBOX_SLOTS; i++) + DEVICE_REG32_W (DEVICE_PA_BASE + PA_REG_MAILBOX_SLOT(0, i), 0); + + + /* Give a few cycles for the disable */ + chipDelay32 (100); + + /* download the firmware */ + memcpy ((UINT32 *)(DEVICE_PA_BASE + PA_MEM_PDSP_IRAM(0)), PDSPcode, sizeof(PDSPcode)); + + /* Reset the PC and enable PDSP0 */ + DEVICE_REG32_W (DEVICE_PA_BASE + PA_REG_PDSP_CTL(0), PA_REG_VAL_PDSP_CTL_ENABLE_PDSP(0)); + + + /* Copy the two destination mac addresses to the mail box slots. + * Mailbox 4 must be written last since this write triggers the firmware to + * update the match information */ + cfg->cmdBuf[0] = BOOT_READ_BITFIELD(cfg->mac0ms, 31, 24); + cfg->cmdBuf[1] = BOOT_READ_BITFIELD(cfg->mac0ms, 23, 16); + cfg->cmdBuf[2] = BOOT_READ_BITFIELD(cfg->mac0ms, 15, 8); + /* Cant use BOOT_READ_BITFIELD for 8 LSBs because it compiles with endian dependency */ + cfg->cmdBuf[3] = chipLower8 (cfg->mac0ms); + cfg->cmdBuf[4] = BOOT_READ_BITFIELD(cfg->mac0ls, 31, 24); + cfg->cmdBuf[5] = BOOT_READ_BITFIELD(cfg->mac0ls, 23, 16); + cfg->cmdBuf[6] = cfg->cmdBuf[7] = 0; + + cfg->cmdBuf[8] = BOOT_READ_BITFIELD(cfg->mac1ms, 31, 24); + cfg->cmdBuf[9] = BOOT_READ_BITFIELD(cfg->mac1ms, 23, 16); + cfg->cmdBuf[10] = BOOT_READ_BITFIELD(cfg->mac1ms, 15, 8); + /* Cant use BOOT_READ_BITFIELD for 8 LSBs because it compiles with endian dependency */ + cfg->cmdBuf[11] = chipLower8 (cfg->mac1ms); + cfg->cmdBuf[12] = BOOT_READ_BITFIELD(cfg->mac1ls, 31, 24); + cfg->cmdBuf[13] = BOOT_READ_BITFIELD(cfg->mac1ls, 23, 16); + + cfg->cmdBuf[14] = BOOT_READ_BITFIELD(cfg->rxQnum, 15, 8); + cfg->cmdBuf[15] = chipLower8 (cfg->rxQnum); + + + /* Give some delay then verify that the mailboxes have been cleared */ + for (i = 0, done = FALSE; ((i < DEVICE_PA_RUN_CHECK_COUNT) && (done == FALSE)); i++) { + chipDelay32 (100); + v = DEVICE_REG32_R (DEVICE_PA_BASE + PA_REG_MAILBOX_SLOT(0, 3)); + if (v == 0) + done = TRUE; + } + + if (done == FALSE) + return (-1); + + return (0); + +} /* hwPaEnable */ + + +/*********************************************************************************************** + * FUNCTION PURPOSE: Disable the PA firmware + *********************************************************************************************** + * DESCRIPTION: All PDSPs are disabled and all mailbox slots cleared + ***********************************************************************************************/ +SINT16 hwPaDisable (void) +{ + UINT32 i, j; + + /* Disable all pdsps, clear all mailboxes */ + for (i = 0; i < DEVICE_PA_NUM_PDSPS; i++) { + + DEVICE_REG32_W (DEVICE_PA_BASE + PA_REG_PDSP_CTL(i), PA_REG_VAL_PDSP_CTL_DISABLE_PDSP); + + for (j = 0; j < PA_NUM_MAILBOX_SLOTS; j++) + DEVICE_REG32_W (DEVICE_PA_BASE + PA_REG_MAILBOX_SLOT(i, j), 0); + + } + + return (0); + +} /* hwPaDisable */ + + + + + + + + + + + + + + + + diff --git a/src/hw/pa/pa_api.h b/src/hw/pa/pa_api.h new file mode 100644 index 0000000..35f63de --- /dev/null +++ b/src/hw/pa/pa_api.h @@ -0,0 +1,32 @@ +#ifndef _PA_API_H +#define _PA_API_H +/***************************************************************************************************** + * FILE PURPOSE: Define the Packet Accelerator API + ***************************************************************************************************** + * FILE NAME: pa_api.h + * + * DESCRIPTION: The boot loader driver API to the packet accelerator is defined + * + *****************************************************************************************************/ + +typedef struct paConfig_s { + + UINT32 mac0ms; /* 32 most significant bits of the mac address */ + UINT32 mac0ls; /* 32 least significant bits of the mac address, in the 16msbs of this word */ + UINT32 mac1ms; /* 32 most significant bits of the mac address */ + UINT32 mac1ls; /* 32 least significant bits of the mac address, in the 16 msbs of this word */ + UINT32 rxQnum; /* Receive packet queue number */ + UINT8 *cmdBuf; /* Buffer used to create PA command */ + +} paConfig_t; + +/* API */ +SINT16 hwPaEnable (const paConfig_t *cfg); +SINT16 hwPaDisable (void); + +#include "hwpafwsw.h" + + + +#endif /* _PA_API_H */ + diff --git a/src/hw/pa/pa_loc.h b/src/hw/pa/pa_loc.h new file mode 100644 index 0000000..9e19fe3 --- /dev/null +++ b/src/hw/pa/pa_loc.h @@ -0,0 +1,29 @@ +#ifndef _PA_LOC_H +#define _PA_LOC_H +/****************************************************************************************** + * FILE PURPOSE: Provide local Packet Accelerator definitions + ****************************************************************************************** + * FILE NAME: pa_loc.h + * + * DESCRIPTION: Defines the packet accelerator sub-system and hardware interface + * + ******************************************************************************************/ + + +#define PA_REG_MAILBOX_SLOT(pdsp, slot) (0x00 + ((pdsp)*0x10) + ((slot)*0x04)) +#define PA_REG_PDSP_CTL(pdsp) (0x1000 + ((pdsp)*0x100)) +#define PA_MEM_PDSP_IRAM(pdsp) (0x10000 + ((pdsp)*0x8000)) + + +/* The pdsp control register */ +#define PA_REG_VAL_PDSP_CTL_ENABLE_PDSP(pcVal) (((pcVal) << 16) | 0x3) +#define PA_REG_VAL_PDSP_CTL_DISABLE_PDSP 0 + +/* Number of mailbox slots for each PDPS */ +#define PA_NUM_MAILBOX_SLOTS 4 + + + + +#endif /* _PA_LOC_H */ + diff --git a/src/hw/plls/pll014phi/cfgpll.c b/src/hw/plls/pll014phi/cfgpll.c new file mode 100644 index 0000000..36af36f --- /dev/null +++ b/src/hw/plls/pll014phi/cfgpll.c @@ -0,0 +1,124 @@ +/******************************************************************************************************** + * FILE PURPOSE: Config level PLL driver + ******************************************************************************************************** + * FILE NAME: cfgpll.c + * + * DESCRIPTION: The boot driver for PLLs that dont have a pll controller, but are controlled + * by registers in config space. + * + *********************************************************************************************************/ +#include "types.h" +#include "target.h" +#include "pllapi.h" + +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + + +/********************************************************************************************************* + * FUNCTION PURPOSE: Configure and enable a pll + ********************************************************************************************************* + * DESCRIPTION: The PLL is configured. If the existing configuration matches the requested one no + * register write is made. + *********************************************************************************************************/ +SINT16 hwPllSetCfgPll (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz) +{ + UINT32 reg; + UINT32 regb; + UINT32 bwAdj; + + UINT16 currentPrediv; + UINT16 currentMult; + UINT16 currentPostdiv; + UINT16 currentBypass; + UINT16 currentBwAdj; + UINT16 currentEnable; + UINT16 currentClkOut; + + reg = DEVICE_REG32_R (base); + regb = DEVICE_REG32_R (base + 4); + + currentPrediv = 1 + BOOT_READ_BITFIELD (reg, 5, 0); + currentMult = 1 + BOOT_READ_BITFIELD (reg, 18, 6); + currentPostdiv = 1 + BOOT_READ_BITFIELD (reg, 22, 19); + currentBypass = BOOT_READ_BITFIELD (reg, 23, 23); + currentBwAdj = 1 + BOOT_READ_BITFIELD (reg, 31, 24) + ((BOOT_READ_BITFIELD (regb, 3, 0)) << 8); + currentEnable = BOOT_READ_BITFIELD(regb, 14, 14); + currentClkOut = BOOT_READ_BITFIELD(regb, 13, 13); + + /* The PLL is currently enabled and connected if bypass == 0, enable == 1, clkout == 1 */ + + if ( (currentBypass == 0) && + (currentPrediv == prediv) && + (currentMult == mult) && + (currentPostdiv == postdiv) && + (currentEnable == 0) && + (currentClkOut == 1) && + (currentBwAdj == (mult >> 1)) ) + return (0); + + + /* bwAdj is based only on the mult value */ + bwAdj = (mult >> 1) - 1; + + /* Multiplier / divider values are input as 1 less then the desired value */ + if (prediv > 0) + prediv -= 1; + + if (mult > 0) + mult -= 1; + + if (postdiv > 0) + postdiv -= 1; + + /* Set bit 14 in register 1 to disable the PLL (assert reset) */ + regb = BOOT_SET_BITFIELD(regb, 1, 14, 14); + DEVICE_REG32_W (base + 4, regb); + + /* Setup the PLL. Assert bypass */ + reg = BOOT_SET_BITFIELD (reg, prediv, 5, 0); + reg = BOOT_SET_BITFIELD (reg, mult, 18, 6); + reg = BOOT_SET_BITFIELD (reg, postdiv, 22, 19); + reg = BOOT_SET_BITFIELD (reg, 1, 23, 23); /* Bypass must be enabled */ + reg = BOOT_SET_BITFIELD (reg, (bwAdj & 0xff), 31, 24); + + DEVICE_REG32_W (base, reg); + + /* The 4 MS Bits of bwadj */ + regb = BOOT_SET_BITFIELD (regb, (bwAdj >> 8), 3, 0); + DEVICE_REG32_W (base + 4, regb); + + + /* Reset must be asserted for at least 5us. Give a huge amount of padding here to be safe + * (the factor of 100) */ + chipDelay32 (5 * chipFreqMhz * 100); + + + /* Clear bit 14 in register 1 to re-enable the pll */ + regb = BOOT_SET_BITFIELD(regb, 0, 14, 14); + DEVICE_REG32_W (base + 4, regb); + + /* Need to wait 100,000 output PLL cycles before releasing bypass and setting + * up the clk output */ + chipDelay32 (chipFreqMhz * 100000 / pllFreqMhz); + + + /* Disable the bypass */ + reg = BOOT_SET_BITFIELD (reg, 0, 23, 23); /* The value 0 disables the bypass */ + DEVICE_REG32_W (base, reg); + + /* Enable the output source (set bit 13) */ + regb = BOOT_SET_BITFIELD(regb, 1, 13, 13); + DEVICE_REG32_W (base + 4, regb); + + return (0); + +} /* hwPllSetCfgPll */ + + + + diff --git a/src/hw/plls/pll014phi/cfgpll2.c b/src/hw/plls/pll014phi/cfgpll2.c new file mode 100644 index 0000000..c4dfebd --- /dev/null +++ b/src/hw/plls/pll014phi/cfgpll2.c @@ -0,0 +1,118 @@ +/******************************************************************************************************** + * FILE PURPOSE: Config level PLL driver + ******************************************************************************************************** + * FILE NAME: cfgpll.c + * + * DESCRIPTION: The boot driver for PLLs that dont have a pll controller, but are controlled + * by registers in config space. + * + * This driver differs from cfgpll! In this file the reset is controlled by + * bit 13 in register b, not bit 14!. + * + *********************************************************************************************************/ +#include "types.h" +#include "target.h" +#include "pllapi.h" + +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + + +/********************************************************************************************************* + * FUNCTION PURPOSE: Configure and enable a pll + ********************************************************************************************************* + * DESCRIPTION: The PLL is configured. If the existing configuration matches the requested one no + * register write is made. + *********************************************************************************************************/ +SINT16 hwPllSetCfg2Pll (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz) +{ + UINT32 reg; + UINT32 regb; + UINT32 bwAdj; + + UINT16 currentPrediv; + UINT16 currentMult; + UINT16 currentPostdiv; + UINT16 currentBypass; + UINT16 currentBwAdj; + UINT16 currentEnable; + + reg = DEVICE_REG32_R (base); + regb = DEVICE_REG32_R (base + 4); + + currentPrediv = 1 + BOOT_READ_BITFIELD (reg, 5, 0); + currentMult = 1 + BOOT_READ_BITFIELD (reg, 18, 6); + currentPostdiv = 1 + BOOT_READ_BITFIELD (reg, 22, 19); + currentBypass = BOOT_READ_BITFIELD (reg, 23, 23); + currentBwAdj = 1 + BOOT_READ_BITFIELD (reg, 31, 24) + ((BOOT_READ_BITFIELD (regb, 3, 0)) << 8); + currentEnable = BOOT_READ_BITFIELD(regb, 13, 13); + + /* The PLL is currently enabled and connected if bypass == 0, enable == 1, clkout == 1 */ + + if ( (currentBypass == 0) && + (currentPrediv == prediv) && + (currentMult == mult) && + (currentPostdiv == postdiv) && + (currentEnable == 0) && + (currentBwAdj == (mult >> 1)) ) + return (0); + + + /* bwAdj is based only on the mult value */ + bwAdj = (mult >> 1) - 1; + + /* Multiplier / divider values are input as 1 less then the desired value */ + if (prediv > 0) + prediv -= 1; + + if (mult > 0) + mult -= 1; + + if (postdiv > 0) + postdiv -= 1; + + /* Set bit 13 in register 1 to disable the PLL (assert reset) */ + regb = BOOT_SET_BITFIELD(regb, 1, 13, 13); + DEVICE_REG32_W (base + 4, regb); + + /* Setup the PLL. Assert bypass */ + reg = BOOT_SET_BITFIELD (reg, prediv, 5, 0); + reg = BOOT_SET_BITFIELD (reg, mult, 18, 6); + reg = BOOT_SET_BITFIELD (reg, postdiv, 22, 19); + reg = BOOT_SET_BITFIELD (reg, 1, 23, 23); /* Bypass must be enabled */ + reg = BOOT_SET_BITFIELD (reg, (bwAdj & 0xff), 31, 24); + + DEVICE_REG32_W (base, reg); + + /* The 4 MS Bits of bwadj */ + regb = BOOT_SET_BITFIELD (regb, (bwAdj >> 8), 3, 0); + DEVICE_REG32_W (base + 4, regb); + + + /* Reset must be asserted for at least 5us. Give a huge amount of padding here to be safe + * (the factor of 100) */ + chipDelay32 (5 * chipFreqMhz * 100); + + + /* Clear bit 13 in register 1 to re-enable the pll */ + regb = BOOT_SET_BITFIELD(regb, 0, 13, 13); + DEVICE_REG32_W (base + 4, regb); + + /* Need to wait 100,000 output PLL cycles before releasing bypass and setting + * up the clk output */ + chipDelay32 (chipFreqMhz * 100000 / pllFreqMhz); + + + /* Disable the bypass */ + reg = BOOT_SET_BITFIELD (reg, 0, 23, 23); /* The value 0 disables the bypass */ + DEVICE_REG32_W (base, reg); + + return (0); + +} /* hwPllSetCfg2Pll */ + + diff --git a/src/hw/plls/pll014phi/pll.c b/src/hw/plls/pll014phi/pll.c new file mode 100644 index 0000000..d709d11 --- /dev/null +++ b/src/hw/plls/pll014phi/pll.c @@ -0,0 +1,152 @@ +/************************************************************************************* + * FILE PURPOSE: Provide PLL control functions + ************************************************************************************* + * FILE NAME: pll.c + * + * DESCRIPTION: Provides functions to control the pll + * + *************************************************************************************/ +#include "types.h" +#include "ibl.h" +#include "pllloc.h" +#include "pllapi.h" +#include "target.h" + +#define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y) +#define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x)) + +#define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) ) +#define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y) +#define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) ) + + +typedef enum { + HW_PLL_DO_NOT_ENABLE_PLL, + HW_PLL_ENABLE_PLL +} hwPllEnable_t; + +/********************************************************************************* + * FUNCTION PURPOSE: Provide a delay loop + ********************************************************************************* + * DESCRIPTION: Generates a delay, units of cycles + *********************************************************************************/ +void hw_pll_delay (UINT32 del) +{ + UINT32 i; + volatile UINT32 j; + + for (i = j = 0; i < del; i++) + j = j + 1; + +} /* hw_pll_delay */ + + +/********************************************************************************** + * FUNCTION PURPOSE: Enables the pll to the specified multiplier + ********************************************************************************** + * DESCRIPTION: Sets up the pll + **********************************************************************************/ +SINT16 hwPllSetPll (UINT32 pllNum, UINT32 prediv, UINT32 mult, UINT32 postdiv) +{ + UINT32 ctl; + UINT32 secctl; + UINT32 status; + UINT32 pmult; + UINT32 pdiv; + UINT32 pllBase; + UINT32 i; + SINT16 ret = 0; + + + /* Mutliplier/divider values of 0 are invalid */ + if (prediv == 0) + prediv = 1; + + if (mult == 0) + mult = 1; + + if (postdiv == 0) + postdiv = 1; + + /* Get the base address of the pll */ + pllBase = (UINT32) DEVICE_PLL_BASE(pllNum); + + /* Program pllen=0 (pll bypass), pllrst=1 (reset pll), pllsrc = 0 */ + ctl = DEVICE_REG32_R (pllBase + PLL_REG_CTL); + ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLEN | PLL_REG_CTL_FIELD_PLLENSRC | PLL_REG_CTL_FIELD_PLLDIS); + DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl); + + + /* Enable secondary controller pll bypass */ + secctl = DEVICE_REG32_R (pllBase + PLL_REG_SECCTL); + secctl = secctl | PLL_REG_SECCTL_FIELD_BYPASS; + DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl); + + /* Reset the PLL */ + ctl = ctl | PLL_REG_CTL_FIELD_PLLRST; + DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl); + + /* Enable the pll divider */ + secctl = DEVICE_REG32_R (pllBase + PLL_REG_SECCTL); + secctl = PLL_REG_SECCTL_SET_POSTDIV(secctl,postdiv-1); + secctl = PLL_REG_SECCTL_ENABLE_POSTDIV(secctl); + DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl); + + + /* Some PLLs like the rpll used in Nysh have an external (chip register) PLL predivider */ + if (chipPllExternalPrediv(pllNum) == FALSE) { + pdiv = (UINT32) (((prediv-1) & PLL_REG_PREDIV_FIELD_RATIOm1) | PLL_REG_PREDIV_FIELD_ENABLE); + DEVICE_REG32_W (pllBase + PLL_REG_PREDIV, pdiv); + } else + chipPllSetExternalPrediv(pllNum, prediv - 1); + + /* The rpll used in Nysh has both external and internal multiplier components. The external + * is set first because it modifies the internal. The value returned by chipPllExternalMult + * will be modified to take into account the value programed by the chip regsiters. This + * mult value input into chipPllExternalMult is the actual desired multiplier value, not + * the desired value - 1 */ + pmult = chipPllExternalMult(pllNum, mult); + pmult = pmult & PLL_REG_PLLM_FIELD_MULTm1; + DEVICE_REG32_W (pllBase + PLL_REG_PLLM, pmult); + + /* Some PLLs like the rpll used in Nysh require bandwidth adjustment which is controlled + * through a chip level register. Devices that don't require this simply define + * this function to an empty statement */ + chipPllExternalBwAdj (pllNum, mult); + + + /* Wait a while for the pll to reset */ + hw_pll_delay (2000/7); + + /* set pllrst to 0 to deassert pll reset */ + ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLRST); + DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl); + + + /* wait for the pll to lock, but don't trap if lock is never read */ + for (i = 0; i < 100; i++) { + hw_pll_delay (2000/7); + status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT); + if ( (status & PLL_REG_STATUS_FIELD_LOCK) != 0 ) + break; + } + + /* Enable the pll even if the lock failed. Return a warning. */ + if (i == 100) + ret = -1; + + /* Clear the secondary controller bypass bit */ + secctl = secctl & ~PLL_REG_SECCTL_FIELD_BYPASS; + DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl); + + + /* Set pllen to 1 to enable pll mode */ + ctl = ctl | PLL_REG_CTL_FIELD_PLLEN; + DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl); + + return (ret); + + +} /* hwPllSetPll */ + + diff --git a/src/hw/plls/pll014phi/pllloc.h b/src/hw/plls/pll014phi/pllloc.h new file mode 100644 index 0000000..c9c4eb6 --- /dev/null +++ b/src/hw/plls/pll014phi/pllloc.h @@ -0,0 +1,86 @@ +#ifndef _PLLLOC_H +#define _PLLLOC_H +/************************************************************************************** + * FILE PURPOSE: Local pll definitions + ************************************************************************************** + * FILE NAME: pllloc.h + * + * DESCRIPTION: Local definitions for the pll driver + **************************************************************************************/ + +/* Register offsets */ +#define PLL_REG_RSTYPE 0x00e4 +#define PLL_REG_RSCTL 0x00e8 +#define PLL_REG_RSCFG 0x00ec +#define PLL_REG_CTL 0x0100 +#define PLL_REG_SECCTL 0x0108 +#define PLL_REG_PLLM 0x0110 +#define PLL_REG_PREDIV 0x0114 +#define PLL_REG_POSTDIV 0x0128 +#define PLL_REG_CMD 0x0138 +#define PLL_REG_PLLSTAT 0x013c +#define PLL_REG_CKCTL 0x0154 + +/* PLL constants */ + +/* Bit fields */ +/* Reset type register */ +#define PLL_REG_RSTYPE_FIELD_POWER_ON_RESET (1<<0) +#define PLL_REG_RSTYPE_FIELD_RESET_PI (1<<1) +#define PLL_REG_RSTYPE_FIELD_PLL_CTRL (1<<2) +#define PLL_REG_RSTYPE_FIELD_RESET_REQ (0xff00) /* Bits 8-15 */ +#define PLL_REG_RSTYPE_FIELD_EMU_0 (1<<28) +#define PLL_REG_RSTYPE_FIELD_EMU_1 (1<<29) + +#define PLL_REG_RSTYPE_EXTRACT_RESET_REQ(x) (((x) & PLL_REG_RSTYPE_FIELD_RESET_REQ) >> 8) + +/* Reset cfg register */ +#define PLL_REG_RSCFG_FIELD_RESET_REQ_TYPE (0x00ff) +#define PLL_REG_RSCFG_FIELD_RESET_PI_TYPE (1<<12) +#define PLL_REG_RSCFG_FIELD_RESET_PLL_CTRL_TYPE (1<<13) +#define PLL_REG_RSCFG_FIELD_POWER_ON_RESET (1<<29) + + +/* Reset ctrl register */ +#define PLL_REG_RSCTL_VALUE_SOFTRST_DISABLED (1<<16) +#define PLL_REG_RSCTL_VALUE_KEY (0x5A69) + + +/* Ctl register */ +#define PLL_REG_CTL_FIELD_PLLEN (1<<0) +#define PLL_REG_CTL_FIELD_PLLRST (1<<3) +#define PLL_REG_CTL_FIELD_PLLDIS (1<<4) +#define PLL_REG_CTL_FIELD_PLLENSRC (1<<5) + +/* Secondary control register */ +#define PLL_REG_SECCTL_FIELD_BYPASS (1<<23) +#define PLL_REG_SECCTL_SET_POSTDIV(x,v) BOOT_SET_BITFIELD((x),(v),16,16) +#define PLL_REG_SECCTL_ENABLE_POSTDIV(x) BOOT_SET_BITFIELD((x),1,19,19) + + +/* Pll multiplier register */ +#define PLL_REG_PLLM_FIELD_MULTm1 (0x3f<<0) + +/* Prediv register */ +#define PLL_REG_PREDIV_FIELD_RATIOm1 (0x1f<<0) +#define PLL_REG_PREDIV_FIELD_ENABLE (1<<15) + +/* Postdiv register */ +#define PLL_REG_POSTDIV_FIELD_RATIO (0x3f <<0) +#define PLL_REG_POSTDIV_FIELD_ENABLE (1<<15) +#define PLL_REG_POSTDIV_VALUE_DISABLED 0 + +/* Status register */ +#define PLL_REG_STATUS_FIELD_GOSTAT (1<<0) +#define PLL_REG_STATUS_FIELD_LOCK (1<<1) + +/* CKCTL register */ +#define PLL_REG_CKCTL_ALNBYP (1<<0) + +/* Cmd register */ +#define PLL_REG_CMD_GOSET (1<<0) + +#endif /* _PLLLOC_H */ + + + diff --git a/src/hw/plls/pllapi.h b/src/hw/plls/pllapi.h index 3ff1a0c..a37340d 100644 --- a/src/hw/plls/pllapi.h +++ b/src/hw/plls/pllapi.h @@ -58,6 +58,8 @@ int16 hwPllSetPll (uint32 pllNum, uint32 prediv, uint32 mult, uint32 postdiv); int16 hwPllDisable (uint32 pllNum); int16 hwPllEnable (uint32 pllNum); +SINT16 hwPllSetCfgPll (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz); +SINT16 hwPllSetCfg2Pll (UINT32 base, UINT16 prediv, UINT16 mult, UINT16 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz); /** * @def pll_POR_RESET diff --git a/src/hw/pscs/psc2/pscloc.h b/src/hw/pscs/psc2/pscloc.h index 3570635..e755fe9 100644 --- a/src/hw/pscs/psc2/pscloc.h +++ b/src/hw/pscs/psc2/pscloc.h @@ -47,10 +47,6 @@ *************************************************************************************/ -#define BOOTBITMASK(x,y) ( ( ( ((uint32)1 << (((uint32)x)-((uint32)y)+(uint32)1) ) - (uint32)1 ) ) << ((uint32)y) ) -#define BOOT_READ_BITFIELD(z,x,y) (((uint32)z) & BOOTBITMASK(x,y)) >> (y) -#define BOOT_SET_BITFIELD(z,f,x,y) (((uint32)z) & ~BOOTBITMASK(x,y)) | ( (((uint32)f) << (y)) & BOOTBITMASK(x,y) ) - /* Register offsets */ #define PSC_REG_PTCMD 0x120 #define PSC_REG_PSTAT 0x128 diff --git a/src/hw/qm/qm.c b/src/hw/qm/qm.c new file mode 100644 index 0000000..b7a0e69 --- /dev/null +++ b/src/hw/qm/qm.c @@ -0,0 +1,213 @@ +/****************************************************************************************** + * FILE PURPOSE: Boot queue manager driver + ****************************************************************************************** + * FILE NAME: qm.c + * + * DESCRIPTION: The boot loader queue manager driver. This driver uses a very simple + * setup on the queue manager, with a single link ram and a single + * memory region. The descriptors are configured as host descriptors + * and have the minimum 32 byte size. + * + * For the boot driver queue register C is not written. It is important + * to the boot loader if packets are pushed/popped from the head or + * tail of a queue. + * + ******************************************************************************************/ +#include "types.h" +#include "qm_loc.h" +#include "qm_api.h" +#include "device.h" +#include + +/******************************************************************************************* + * FUNCTION PURPOSE: Pop a descriptor off of a queue + ******************************************************************************************* + * DESCRIPTION: The descriptor is read from queue register D. + *******************************************************************************************/ +qmHostDesc_t *hwQmQueuePop (UINT32 qnum) +{ + qmHostDesc_t *hd; + UINT32 uhd; + + /* Strip the descriptor size info */ + uhd = DEVICE_REG32_R (DEVICE_QM_MANAGER_QUEUES_BASE + QM_REG_QUEUE_REGD(qnum)); + uhd = uhd & ~0xf; + hd = (qmHostDesc_t *)uhd; + + return (hd); +} /* hwQmQueuePop */ + +/******************************************************************************************* + * FUNCTION PURPOSE: Return the number of descriptors on a queue + ******************************************************************************************* + * DESCRIPTION: The queue count is returned + *******************************************************************************************/ +UINT32 hwQmQueueCount (UINT32 qnum) +{ + UINT32 rega; + + rega = DEVICE_REG32_R (DEVICE_QM_QUEUE_STATUS_BASE + QM_REG_QUEUE_REGA(qnum)); + rega = BOOT_READ_BITFIELD (rega, QM_QA_ENTRY_COUNT_MSB, QM_QA_ENTRY_COUNT_LSB); + return (rega); + +} /* hwQmQueueCount */ + +/******************************************************************************************* + * FUNCTION PURPOSE: Set a queue threshold + ******************************************************************************************* + * DESCRIPTION: The queue threshold is enabled. Only high threshold is set, with a threshold + * value of 1. + *******************************************************************************************/ +SINT16 hwQmInitThreshold (UINT32 qnum) +{ + DEVICE_REG32_W (DEVICE_QM_QUEUE_STATUS_BASE + QM_REG_STAT_CFG_REGD(qnum), 0x81); + + return (0); + +} /* hwQmInitThreshold */ + + +/******************************************************************************************* + * FUNCTION PURPOSE: Push a descriptor onto a queue + ******************************************************************************************* + * DESCRIPTION: The descriptor is written to queue register D. No check is made to see + * if the queue number is valid. + *******************************************************************************************/ +void hwQmQueuePush (qmHostDesc_t *hd, UINT32 qnum, UINT32 descrSize) +{ + UINT32 regd; + + regd = ((UINT32) hd | ((descrSize >> 4) - 1)); + + /* Push the descriptor onto the queue */ + DEVICE_REG32_W (DEVICE_QM_MANAGER_QUEUES_BASE + QM_REG_QUEUE_REGD(qnum), regd); + +} /* hwQmQueuePush */ + +/******************************************************************************************* + * FILE PURPOSE: Setup the queue manager + ******************************************************************************************* + * DESCRIPTION: The queue manager is setup using a single linking ram and memory region, + * with fixed descriptor initialization. + * + * Since the linking ram and descriptor regions are configured, it is assumed + * that all queues are currently empty. + * + ********************************************************************************************/ +SINT16 hwQmSetup (qmConfig_t *cfg) +{ + UINT32 v; + UINT32 w; + UINT32 x; + UINT32 i; + qmHostDesc_t *hd; + + /* Verify that alignment requirements */ + if ( (cfg->linkRamBase & (QM_LINKRAM_ALIGN-1)) != 0 ) + return (QM_INVALID_LINKRAM_ALIGNMENT); + + if ( (cfg->memRegionBase & (QM_MEMR_ALIGN-1)) != 0 ) + return (QM_INVALID_MEMREGION_ALIGNMENT); + + /* Verify linkram sizing is in range */ + if ( (cfg->linkRamSize & ~QM_REG_LINKRAM_SIZE_MAX_MASK) != 0 ) + return (QM_INVALID_LINKRAM_SIZE); + + /* Verify there is enough linkram to cover the single memory region */ + if (cfg->linkRamSize < cfg->memRegNumDescriptors) + return (QM_INVALID_LINKRAM_RAM_SIZE); + + + /* Linking RAM info */ + DEVICE_REG32_W (DEVICE_QM_MANAGER_BASE + QM_REG_LINKRAM_BASE(0), cfg->linkRamBase); + DEVICE_REG32_W (DEVICE_QM_MANAGER_BASE + QM_REG_LINKRAM_SIZE(0), cfg->linkRamSize); + DEVICE_REG32_W (DEVICE_QM_MANAGER_BASE + QM_REG_LINKRAM_BASE(1), 0); + + /* Memory region 0 info */ + DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_BASE_ADDR(0), cfg->memRegionBase); + DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_START_IDX(0), 0); + + /* Calculate the 2 fields in the descriptor setup register. Bits 0-3 specifiy + * the total memory size rounded up to the next higher power of two, and + * is expresses as 2^(n - 5). So for example if you have 20 descriptors + * The next higher power of 2 that exceeds this is 32, which is 2^5, so the value 0 (5-5) + * is placed in this field */ + v = (31 - chipLmbd (1, cfg->memRegNumDescriptors)); + if (v >= 4) + v = v - 4; + else + v = 0; + + /* Add the descriptor size field */ + QM_REG_VAL_DESC_SETUP_SET_DESC_SIZE(v, QM_DESC_SIZE_BYTES); + + DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_DESC_SETUP(0), v); + + + /* Now format the descriptors and put them in a queue */ + for (i = 0, v = cfg->memRegionBase; i < cfg->memRegNumDescriptors; i++, v += QM_DESC_SIZE_BYTES) { + + hd = (qmHostDesc_t *)v; + memset (hd, 0, sizeof(qmHostDesc_t)); + + hd->descInfo = QM_DESC_DEFAULT_DESCINFO; + hd->packetInfo = QM_DESC_DEFAULT_PINFO; + + if (QM_DESC_INFO_GET_PSINFO_LOC(hd->descInfo) == QM_DESC_PSINFO_IN_DESCR) { + if (QM_PKT_INFO_GET_EPIB(hd->packetInfo) == QM_DESC_PINFO_EPIB) + w = QM_DESC_SIZE_BYTES - 32 - 16; /* 32 bytes min descriptor size, 16 bytes extended info */ + else + w = QM_DESC_SIZE_BYTES - 32; + } else + w = 0; + + QM_PKT_INFO_SET_PSINFO_SIZE(hd->packetInfo, (w >> 2)); + + + /* Push the descriptor onto the queue */ + x = deviceLocalAddrToGlobal (v); + + DEVICE_REG32_W (DEVICE_QM_MANAGER_QUEUES_BASE + QM_REG_QUEUE_REGD(cfg->destQ), x); + + } + + return (QM_OK); + +} /* hwQmSetup */ + + +/**************************************************************************************** + * FUNCTION PURPOSE: Disable the QM + **************************************************************************************** + * DESCRIPTION: The QM is reset by clearing the linking ram and region 0 information + ****************************************************************************************/ +void hwQmTeardown (void) +{ + UINT32 i; + + /* Linking RAM info */ + for (i = 0; i < DEVICE_QM_NUM_LINKRAMS; i++) { + DEVICE_REG32_W (DEVICE_QM_MANAGER_BASE + QM_REG_LINKRAM_BASE(i), 0); + DEVICE_REG32_W (DEVICE_QM_MANAGER_BASE + QM_REG_LINKRAM_SIZE(i), 0); + } + + /* Memory region info */ + for (i = 0; i < DEVICE_QM_NUM_MEMREGIONS; i++) { + DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_BASE_ADDR(i), 0); + DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_START_IDX(i), 0); + DEVICE_REG32_W (DEVICE_QM_DESC_SETUP_BASE + QM_REG_MEMR_DESC_SETUP(i), 0); + } + +} /* hwQmTeardown */ + + + + + + + + + + + + diff --git a/src/hw/qm/qm_api.h b/src/hw/qm/qm_api.h new file mode 100644 index 0000000..a985fae --- /dev/null +++ b/src/hw/qm/qm_api.h @@ -0,0 +1,109 @@ +#ifndef _QM_API_H +#define _QM_API_H +/******************************************************************************************* + * FILE PURPOSE: Boot loader queue manager API definition + ******************************************************************************************* + * FILE NAME: qm_api.h + * + * DESCRIPTION: Defines the stripped down QM driver API to the boot loader. + * + ********************************************************************************************/ + +/* return values */ +#define QM_OK 0 +#define QM_INVALID_LINKRAM_ALIGNMENT -1 +#define QM_INVALID_MEMREGION_ALIGNMENT -2 +#define QM_INVALID_LINKRAM_SIZE -3 +#define QM_INVALID_LINKRAM_RAM_SIZE -4 /* Not enough link ram for the number of descriptors */ + + +/* Memory alignment requirements (bytes) */ +#define QM_LINKRAM_ALIGN 4 +#define QM_MEMR_ALIGN 16 /* Not specified in the doc */ + +/* The driver supports only a single descriptor size */ +#define QM_DESC_SIZE_BYTES 64 + +/* QM setup configuration */ +typedef struct qmConfig_s { + + UINT32 linkRamBase; + UINT32 linkRamSize; + + UINT32 memRegionBase; + UINT32 memRegNumDescriptors; + + UINT32 destQ; /* Where the initialized descriptors are placed */ + +} qmConfig_t; + +typedef struct qmHostDesc_s { + /** Descriptor type, packet type, protocol specific region location, packet length */ + UINT32 descInfo; + /** Source tag, Destination tag */ + UINT32 tagInfo; + /** EPIB present, PS valid word count, error flags, PS flags, return policy, return push policy, + * packet return QM number, packet return queue number */ + UINT32 packetInfo; + /** Number of valid data bytes in the buffer */ + UINT32 buffLen; + /** Byte aligned memory address of the buffer associated with this descriptor */ + UINT32 buffPtr; + /** 32-bit word aligned memory address of the next buffer descriptor */ + UINT32 nextBDPtr; + /** Completion tag, original buffer size */ + UINT32 origBufferLen; + /** Original buffer pointer */ + UINT32 origBuffPtr; + /** Optional EPIB word0 */ + UINT32 timeStamp; + /** Optional EPIB word1 */ + UINT32 softwareInfo0; + /** Optional EPIB word2 */ + UINT32 softwareInfo1; + /** Optional EPIB word3 */ + UINT32 softwareInfo2; + /** Optional protocol specific data */ + UINT32 psData; +} qmHostDesc_t; + + +/* Descriptor values */ +/* Descriptor Info: Descriptor type is host with any protocol specific info in the descriptor */ +#define QM_DESC_TYPE_HOST 0 +#define QM_DESC_PSINFO_IN_DESCR 0 +#define QM_DESC_DEFAULT_DESCINFO (QM_DESC_TYPE_HOST << 30) | \ + (QM_DESC_PSINFO_IN_DESCR << 22) +#define QM_DESC_INFO_GET_PSINFO_LOC(x) BOOT_READ_BITFIELD((x), 22, 22) + +#define QM_DESC_DESCINFO_SET_PKT_LEN(x,v) (x) = BOOT_SET_BITFIELD((x), (v), 21, 0) +#define QM_DESC_DESCINFO_GET_PKT_LEN(x) BOOT_READ_BITFIELD((x), 21, 0) + + +/* Packet Info */ +#define QM_DESC_PINFO_EPIB 1 +#define QM_DESC_PINFO_RETURN_OWN 1 +#define QM_DESC_DEFAULT_PINFO (QM_DESC_PINFO_EPIB << 31) | \ + (QM_DESC_PINFO_RETURN_OWN << 15) +#define QM_PKT_INFO_GET_EPIB(x) BOOT_READ_BITFIELD((x), 31, 31) +#define QM_PKT_INFO_SET_PSINFO_SIZE(x,v) (x) = BOOT_SET_BITFIELD((x), (v), 29, 24) + + + +#define QM_DESC_PINFO_SET_QM(x,v) (x) = BOOT_SET_BITFIELD((x), (v), 13, 12) +#define QM_DESC_PINFO_SET_QUEUE(x,v) (x) = BOOT_SET_BITFIELD((x), (v), 11, 0) + + +/* prototypes */ +qmHostDesc_t *hwQmQueuePop (UINT32 qnum); +void hwQmQueuePush (qmHostDesc_t *hd, UINT32 qnum, UINT32 descSize); +SINT16 hwQmSetup (qmConfig_t *cfg); +UINT32 hwQmQueueCount (UINT32 qnum); +void hwQmTeardown (void); +SINT16 hwQmInitThreshold (UINT32 qnum); + + + + +#endif /* _QM_API_H */ + diff --git a/src/hw/qm/qm_loc.h b/src/hw/qm/qm_loc.h new file mode 100644 index 0000000..aacac84 --- /dev/null +++ b/src/hw/qm/qm_loc.h @@ -0,0 +1,44 @@ +#ifndef _QM_LOC_H +#define _QM_LOC_H +/*************************************************************************************** + * FILE PURPOSE: Queue Manager local definitions + *************************************************************************************** + * FILE NAME: qm_loc.h + * + * DESCRIPTION: Local queue manager definitions + * + ***************************************************************************************/ + +/* Memory map */ +/* Relative to the queue manager region */ +#define QM_REG_REVISION 0x00 +#define QM_REG_DIVERSION 0x08 +#define QM_REG_LINKRAM_BASE(x) (0x0c + 8*(x)) +#define QM_REG_LINKRAM_SIZE(x) (0x10 + 8*(x)) + +/* The queue peek registers (includes thresholds) */ +#define QM_REG_STAT_CFG_REGD(x) (0xc + 16*(x)) + +/* Relative to the descriptor setup region */ +#define QM_REG_MEMR_BASE_ADDR(x) (0x00 + 16*(x)) +#define QM_REG_MEMR_START_IDX(x) (0x04 + 16*(x)) +#define QM_REG_MEMR_DESC_SETUP(x) (0x08 + 16*(x)) + +/* Queues, register A */ +#define QM_REG_QUEUE_REGA(x) (0x00 + 16*(x)) +#define QM_QA_ENTRY_COUNT_MSB 18 +#define QM_QA_ENTRY_COUNT_LSB 0 + +/* Queues, register D */ +#define QM_REG_QUEUE_REGD(x) (0x0c + 16*(x)) + +/* Description region setup */ +#define QM_REG_VAL_DESC_SETUP_SET_DESC_SIZE(x,v) (x) = BOOT_SET_BITFIELD((x),((v) >> 4)-1, 28, 16) + + +/* Maximum linking RAM size mask */ +#define QM_REG_LINKRAM_SIZE_MAX_MASK 0x7ffff + + + +#endif /* _QM_LOC_H */ diff --git a/src/hw/serdes/serdes.c b/src/hw/serdes/serdes.c new file mode 100644 index 0000000..bcdb21d --- /dev/null +++ b/src/hw/serdes/serdes.c @@ -0,0 +1,100 @@ +/*********************************************************************************** + * FILE PURPOSE: Serdes configuration + *********************************************************************************** + * FILE NAME: serdes.c + * + * DESCRIPTION: Performs serdes configurations + * + ***********************************************************************************/ +#include "types.h" +#include "serdes_api.h" +#include "serdesloc.h" +#include "device.h" + + +/************************************************************************************ + * FUNCTION PURPOSE: Enable and configure serdes + ************************************************************************************ + * DESCRIPTION: The serdes is configured and enabled + ************************************************************************************/ +SINT16 hwSerdesConfig (UINT32 sBase, serdesConfig_t *scfg) +{ + UINT32 reg; + UINT32 regb; + SINT32 i; + + + /* If the serdes is already enabled and the new value does not match + * the current value, the serdes is first disabled. Dont compare + * the sleep value in the register, which can be toggled dynamically */ + reg = DEVICE_REG32_R (sBase + SERDES_REG_CFG); + reg = SERDES_SET_CFG_SLEEP(reg, 0); + regb = SERDES_SET_CFG_SLEEP(scfg->cfg, 0); + + chipKickOpenSerdes(sBase); + + if ( (SERDES_GET_ENABLE(reg) == 1) && + (SERDES_GET_ENABLE(scfg->cfg) == 1) && + (reg != regb) ) { + + reg = SERDES_SET_ENABLE(reg, 0); + DEVICE_REG32_W (sBase + SERDES_REG_CFG, reg); + chipDelay32 (100); + } + + + /* Config register. After enable it takes upt to 350ns, or 200 cycles to + * stabalize. Although these are serdes clock cycles the delay here is + * in cpu cycles. The PLL status will be checked by the peripheral + * using the PLL */ + + + DEVICE_REG32_W (sBase + SERDES_REG_CFG, regb); + chipDelay32 (200); + + /* Some devices have unreliable lock status bits. Add an extra delay + * to allow the serdes to lock */ + chipDelay32 (TARGET_SERDES_LOCK_DELAY); + + + /* rx and tx config registers */ + for (i = 0; i < scfg->nLanes; i++) { + + DEVICE_REG32_W (sBase + SERDES_REG_RX(i), scfg->rxCfg[i]); + DEVICE_REG32_W (sBase + SERDES_REG_TX(i), scfg->txCfg[i]); + + } + + chipKickClosedSerdes(sBase); + + return (0); + +} /* hwSerdesConfig */ + + + +/******************************************************************************************* + * FUNCTION PURPOSE: Wait for a serdes lock on lane 0 + ******************************************************************************************* + * DESCRIPTION: Waits for a lock on lane 0. Doesn't trap if the lock is not found + *******************************************************************************************/ +SINT16 hwSerdesWaitLock (UINT32 statusBase) +{ + UINT32 reg; + UINT32 i; + + for (i = 0; i < 100; i++) { + reg = DEVICE_REG32_R (statusBase); + if (reg & 1) + return (0); + + chipDelay32 (1000); + } + + return (-1); + +} /* hwSerdesWaitLock */ + + + + diff --git a/src/hw/serdes/serdes_api.h b/src/hw/serdes/serdes_api.h new file mode 100644 index 0000000..9e0873b --- /dev/null +++ b/src/hw/serdes/serdes_api.h @@ -0,0 +1,32 @@ +#ifndef _SERDES_API_H +#define _SERDES_API_H +/************************************************************************************************** + * FILE PURPOSE: SERDES API + ************************************************************************************************** + * FILE NAME: serdes_api.h + * + * DESCRIPTION: Defines the serdes configuration functions + **************************************************************************************************/ + +#define SERDES_MAX_LANES 4 + +typedef struct serdesConfig_s { + + UINT32 cfg; + UINT32 nLanes; + UINT32 rxCfg[SERDES_MAX_LANES]; + UINT32 txCfg[SERDES_MAX_LANES]; + +} serdesConfig_t; + + +SINT16 hwSerdesConfig (UINT32 sBase, serdesConfig_t *scfg); +UINT32 hwSerdesInsertMult (UINT32 reg, UINT32 multX4, BOOL *matchFound); +UINT32 hwSerdesFormCfg (UINT32 vin, UINT32 refClkMhzx100, UINT32 linkRateMhz, UINT32 *dataRate, UINT32 dataRateIdx); +UINT32 hwSerdesFormRxCfg (UINT32 v, UINT32 rate, UINT32 enable); +UINT32 hwSerdesFormTxCfg (UINT32 v, UINT32 rate, UINT32 enable); +BOOL hwSerdesIsEnabled (UINT32 sBase); +SINT16 hwSerdesWaitLock (UINT32 statusBase); + + +#endif /* _SERDES_API_H */ diff --git a/src/hw/serdes/serdesloc.h b/src/hw/serdes/serdesloc.h new file mode 100644 index 0000000..0a79bfe --- /dev/null +++ b/src/hw/serdes/serdesloc.h @@ -0,0 +1,37 @@ +#ifndef _SERDES_LOC_H +#define _SERDES_LOC_H +/************************************************************************************************* + * FILE PURPOSE: Local definitions for SERDES + ************************************************************************************************* + * FILE NAME: serdesloc.h + * + * DESCRIPTION: Local serdes definitions + * + *************************************************************************************************/ +#include "target.h" + +/* Offsets */ +#define SERDES_REG_CFG 0 +#define SERDES_REG_RX(x) (4 + 8*(x)) +#define SERDES_REG_TX(x) (8 + 8*(x)) + + +/* Cfg register */ +#define SERDES_SET_CFG_SLEEP(x,v) BOOT_SET_BITFIELD((x),(v),10,10) +#define SERDES_GET_ENABLE(x) BOOT_READ_BITFIELD((x),0,0) +#define SERDES_SET_ENABLE(x,v) BOOT_SET_BITFIELD((x),(v),0,0) +#define SERDES_SET_MULT(x,v) BOOT_SET_BITFIELD((x),(v),7,1) +#define SERDES_SET_VRANGE(x,v) BOOT_SET_BITFIELD((x),(v),9,9) + + +/* Rx Cfg register */ +#define SERDES_RX_CFG_SET_ENABLE(x,v) BOOT_SET_BITFIELD((x),(v),0,0) +#define SERDES_RX_CFG_SET_RATE(x,v) BOOT_SET_BITFIELD((x),(v),5,4) + +/* Tx Cfg register */ +#define SERDES_TX_CFG_SET_ENABLE(x,v) BOOT_SET_BITFIELD((x),(v),0,0) +#define SERDES_TX_CFG_SET_RATE(x,v) BOOT_SET_BITFIELD((x),(v),5,4) + + +#endif /* _SERDES_LOC_H */ + diff --git a/src/hw/sgmii/sgmii.c b/src/hw/sgmii/sgmii.c index 15a63e6..54f4238 100644 --- a/src/hw/sgmii/sgmii.c +++ b/src/hw/sgmii/sgmii.c @@ -81,11 +81,19 @@ int32 hwSgmiiConfig (int32 port, iblSgmii_t *iblSgmii) SGMII_ACCESS(port, TARGET_SGMII_MR_ADV_ABILITY) = iblSgmii->adviseAbility; +#ifdef TARGET_SGMII_EXTERNAL_SERDES + + targetSgmiiSerdesConfig (port, (void *)iblSgmii); + +#else + /* Serdes configuration */ SGMII_ACCESS(port, TARGET_SGMII_TX_CFG) = iblSgmii->txConfig; SGMII_ACCESS(port, TARGET_SGMII_RX_CFG) = iblSgmii->rxConfig; SGMII_ACCESS(port, TARGET_SGMII_AUX_CFG) = iblSgmii->auxConfig; +#endif + return (0); } diff --git a/src/ibl.h b/src/ibl.h index 9cd5d27..200a86a 100644 --- a/src/ibl.h +++ b/src/ibl.h @@ -112,6 +112,12 @@ typedef struct iblEthBootInfo_s */ #define ibl_ETH_PORT_FROM_RBL -1 /**< The ethernet port used is the same one used during the ROM boot load process. */ + +/** + * @def ibl_PORT_SWITCH_ALL + */ +#define ibl_PORT_SWITCH_ALL -2 /**< The ethernet subsystem is connected to a switch, and + all ports on the subsystem should be configured */ /** @@ -179,10 +185,119 @@ typedef struct iblEmif3p1_s */ typedef struct iblEmif4p0_s { - uint32 dummy; /**< placeholder */ + uint32 registerMask; /**< Identifies which registers will be configured */ + uint32 sdRamConfig; /**< SDRAM Config Register */ + uint32 sdRamConfig2; /**< SDRAM Config2 Register */ + uint32 sdRamRefreshCtl; /**< SDRAM Refresh Control Register */ + uint32 sdRamTiming1; /**< SDRAM Timing 1 Register */ + uint32 sdRamTiming2; /**< SDRAM Timing 2 Register */ + uint32 sdRamTiming3; /**< SDRAM Timing 3 Register */ + uint32 lpDdrNvmTiming; /**< LPDDR2-NVM Timing Register */ + uint32 powerManageCtl; /**< Power Management Control Register */ + uint32 iODFTTestLogic; /**< IODFT Test Logic Global Control Register */ + uint32 performCountCfg; /**< Performance Counter Config Register */ + uint32 performCountMstRegSel; /**< Performance Counter Master Region Select Register */ + uint32 readIdleCtl; /**< Read Idle Control Register */ + uint32 sysVbusmIntEnSet; /**< VBUSM Interrupt Enable Set Register */ + uint32 sdRamOutImpdedCalCfg; /**< SDRAM Output Impedance Calibratin Config Register */ + uint32 tempAlterCfg; /**< Temperature Alert Config Register */ + uint32 ddrPhyCtl1; /**< DDR PHY Control 1 Register */ + uint32 ddrPhyCtl2; /**< DDR PHY Control 2 Register */ + uint32 priClassSvceMap; /**< DDR Priority to Class of Service Mapping Register */ + uint32 mstId2ClsSvce1Map; /**< Master ID to Class of Service 1 Mapping Register */ + uint32 mstId2ClsSvce2Map; /**< Master ID to Class of Service 2 Mapping Register */ + uint32 eccCtl; /**< ECC Control Register */ + uint32 eccRange1; /**< ECC Address Range 1 Register */ + uint32 eccRange2; /**< ECC Address Range 2 Register */ + uint32 rdWrtExcThresh; /**< Read Write Execution Threshold Register */ } iblEmif4p0_t; + +/** + * @defgroup iblEmif4Select Defines the EMIF4 registers configured by IBL + * + * @ingroup iblEmif4Select + * @{ + * @def ibl_EMIF4_ENABLE_sdRamConfig + */ +#define ibl_EMIF4_ENABLE_sdRamConfig (1 << 0) + +/** @def ibl_EMIF4_ENABLE_sdRamConfig2 */ +#define ibl_EMIF4_ENABLE_sdRamConfig2 (1 << 1) + +/** @def ibl_EMIF4_ENABLE_sdRamRefreshCtl */ +#define ibl_EMIF4_ENABLE_sdRamRefreshCtl (1 << 2) + +/** @def ibl_EMIF4_ENABLE_sdRamTiming1 */ +#define ibl_EMIF4_ENABLE_sdRamTiming1 (1 << 3) + +/** @def ibl_EMIF4_ENABLE_sdRamTiming2 */ +#define ibl_EMIF4_ENABLE_sdRamTiming2 (1 << 4) + +/** @def ibl_EMIF4_ENABLE_sdRamTiming3 */ +#define ibl_EMIF4_ENABLE_sdRamTiming3 (1 << 5) + +/** @def ibl_EMIF4_ENABLE_lpDdrNvmTiming */ +#define ibl_EMIF4_ENABLE_lpDdrNvmTiming (1 << 6) + +/** @def ibl_EMIF4_ENABLE_powerManageCtl */ +#define ibl_EMIF4_ENABLE_powerManageCtl (1 << 7) + +/** @def ibl_EMIF4_ENABLE_iODFTTestLogic */ +#define ibl_EMIF4_ENABLE_iODFTTestLogic (1 << 8) + +/** @def ibl_EMIF4_ENABLE_performCountCfg */ +#define ibl_EMIF4_ENABLE_performCountCfg (1 << 9) + +/** @def ibl_EMIF4_ENABLE_performCountMstRegSel */ +#define ibl_EMIF4_ENABLE_performCountMstRegSel (1 << 10) + +/** @def ibl_EMIF4_ENABLE_readIdleCtl */ +#define ibl_EMIF4_ENABLE_readIdleCtl (1 << 11) + +/** @def ibl_EMIF4_ENABLE_sysVbusmIntEnSet */ +#define ibl_EMIF4_ENABLE_sysVbusmIntEnSet (1 << 12) + +/** @def ibl_EMIF4_ENABLE_sdRamOutImpdedCalCfg */ +#define ibl_EMIF4_ENABLE_sdRamOutImpdedCalCfg (1 << 13) + +/** @def ibl_EMIF4_ENABLE_tempAlterCfg */ +#define ibl_EMIF4_ENABLE_tempAlterCfg (1 << 14) + +/** @def ibl_EMIF4_ENABLE_ddrPhyCtl1 */ +#define ibl_EMIF4_ENABLE_ddrPhyCtl1 (1 << 15) + +/** @def ibl_EMIF4_ENABLE_ddrPhyCtl2 */ +#define ibl_EMIF4_ENABLE_ddrPhyCtl2 (1 << 16) + +/** @def ibl_EMIF4_ENABLE_priClassSvceMap */ +#define ibl_EMIF4_ENABLE_priClassSvceMap (1 << 17) + +/** @def ibl_EMIF4_ENABLE_mstId2ClsSvce1Map */ +#define ibl_EMIF4_ENABLE_mstId2ClsSvce1Map (1 << 18) + +/** @def ibl_EMIF4_ENABLE_mstId2ClsSvce2Map */ +#define ibl_EMIF4_ENABLE_mstId2ClsSvce2Map (1 << 11) + +/** @def ibl_EMIF4_ENABLE_eccCtl */ +#define ibl_EMIF4_ENABLE_eccCtl (1 << 19) + +/** @def ibl_EMIF4_ENABLE_eccRange1 */ +#define ibl_EMIF4_ENABLE_eccRange1 (1 << 20) + +/** @def ibl_EMIF4_ENABLE_eccRange2 */ +#define ibl_EMIF4_ENABLE_eccRange2 (1 << 21) + +/** @def ibl_EMIF4_ENABLE_rdWrtExcThresh */ +#define ibl_EMIF4_ENABLE_rdWrtExcThresh (1 << 22) + +/** @def BOOT_EMIF4_ENABLE_ALL */ +#define BOOT_EMIF4_ENABLE_ALL 0x007fffff + +/* @} */ + + /** * @brief * This structure is used to configure the DDR interface @@ -337,6 +452,7 @@ typedef struct iblNand_s uint32 nandPriority; /**< The nand boot priority. @ref iblPeriphPriority */ int32 bootFormat; /**< The format of the boot data file. @ref iblBootFormats */ + int32 cs; /**< The nand chip select space */ iblBinBlob_t blob; /**< Used only if the format is ibl_BOOT_FORMAT_BBLOB */ @@ -486,6 +602,12 @@ extern ibl_t ibl; */ #define ibl_FAIL_CODE_BTBL_FAIL 701 /**< Boot table processing function error */ +/** + * @def ibl_FAIL_CODE_PA + */ +#define ibl_FAIL_CODE_PA 702 /**< Packet Accelerator setup failed */ + + /* @} */ diff --git a/src/make/Makefile b/src/make/Makefile index 5c6547d..a6108f1 100644 --- a/src/make/Makefile +++ b/src/make/Makefile @@ -40,7 +40,7 @@ #* #* DESCRIPTION: Builds the Intermediate Boot Loader (IBL) #* -#* Usage: make c6455 | c6472 | c6474 | c6457 [DEBUG=yes] [ETH=no] [NAND=no] \ +#* Usage: make c6455 | c6472 | c6474 | c6457 | c661x [DEBUG=yes] [ETH=no] [NAND=no] \ #* [BIS=no] [COFF=no] [BLOB=no] [ELF=no] [ENDIAN= both | big | little] [I2C_BUS_ADDR= 0x50 | 0x51] \ #* [COMPACT_I2C=yes] #* @@ -53,7 +53,7 @@ #* make test_build #******************************************************************************************* -IBLS_C6X= c6455 c6472 c6474 c6457 +IBLS_C6X= c6455 c6472 c6474 c6457 c661x EVMS_C6X= evm_c6455 evm_c6472 evm_c6474 diff --git a/src/make/ibl_c661x/i2crom.map.pre b/src/make/ibl_c661x/i2crom.map.pre new file mode 100644 index 0000000..be6f8e0 --- /dev/null +++ b/src/make/ibl_c661x/i2crom.map.pre @@ -0,0 +1,74 @@ +#include "iblcfg.h" +; This file is run through the C preprocessor to get the build time layout information +; The following values must be defined: +; I2C_BUS_ADDR - The I2C bus address of the eeprom holding the ROM boot info and the layout info +; INIT_EXE_FILE - The I2C blocked stage 1 of the ibl +; EXE_FILE_1 - The I2C blocked stage 2 of the ibl, must be the little endian version +; EXE_FILE_2 - The I2C blocked stage 2 of the ibl, must be the big endian version +; PAD_FILE_ID_1 - This pad holds the IBL configuration structure for the little endian version +; PAD_FILE_ID_2 - This pad holds the IBL configuration structure for the big endian version +; +; The section statement directs the ROM boot loader to load the initial endian independent +; portion of the IBL +section +{ + param_index = 0 + boot_mode = 257 + sw_pll_prediv = 1 + sw_pll_mult = 16 + sw_pll_postdiv = 2 + options = 1 + + core_freq_mhz = 625 + i2c_clk_freq_khz = 200 + + dev_addr_ext = I2C_BUS_ADDR + + multi_i2c_id = 0 + my_i2c_id = 1 + address_delay = 0 + exe_file = INIT_EXE_FILE +} + +; The layout statement defines how the resulting I2C image is layed out. The base address +; of this (given in the dev_addr) statement must be known to the initial IBL program +; at compile time. The layout block is simple a group of 32 bit i2c addresses, so +; the order of the exe_file and pad_file_id statements must be configured so as to +; match the definition of struct iblI2cMap_t defined in ibl.h. +layout +{ + dev_addr = IBL_CFG_I2C_MAP_TABLE_DATA_ADDR ; Defined in iblcfg.h + dev_addr_ext = I2C_BUS_ADDR + file_align = 0x80 + + exe_file = EXE_FILE_1 + pad_file_id = PAD_FILE_ID_1 + + + exe_file = EXE_FILE_2 + pad_file_id = PAD_FILE_ID_2 +} + +; The pad statements simply provide space for the IBL configuration structures. It is valid to +; have a single configuration structure which is used for both endian values. +pad +{ + pad_file_id = 1 + dev_addr = 0x500 + dev_addr_ext = I2C_BUS_ADDR + len = 0x300 +} + +#if (PAD_FILE_ID_1 != PAD_FILE_ID_2) +pad +{ + pad_file_id = 2 + dev_addr = 0x800 + dev_addr_ext = I2C_BUS_ADDR + len = 0x300 +} +#endif + + + + diff --git a/src/make/ibl_c661x/ibl.cmd b/src/make/ibl_c661x/ibl.cmd new file mode 100644 index 0000000..1a71390 --- /dev/null +++ b/src/make/ibl_c661x/ibl.cmd @@ -0,0 +1,37 @@ +/************************************************************************************ + * FILE PURPOSE: Define the memory usage of the ibl module for the c661x + ************************************************************************************ + * FILE NAME: ibl.cmd + * + * DESCRIPTION: The memory placement for the IBL is defined + * + ************************************************************************************/ + +/* In order to speed build time during debug, the object files are saved in + * both big and little endian format. The include file is generated by + * make to use the correct endian object files + */ +#include "ibl_objs.inc" + + +/* Symbols from the 1st portion of the load, generated by the make process */ +#include "ibl_init_symbols.inc" + +/* Common memory and section areas between ibl_init and ibl */ +#include "ibl_common.inc" + +SECTIONS +{ + .cinit > TEXT + .const > TEXT + .text > TEXT + .switch > TEXT + .far > DATA + .bss > DATA + + .linkram > LINKRAM + .cppi > CPPIRAM + .mac_buffer > PKTRAM + +} + diff --git a/src/make/ibl_c661x/ibl.rmd b/src/make/ibl_c661x/ibl.rmd new file mode 100644 index 0000000..41c1b87 --- /dev/null +++ b/src/make/ibl_c661x/ibl.rmd @@ -0,0 +1,11 @@ +-a +-boot +-e _c_int00 + +ROMS +{ + ROM1: org = 0x0400, length = 0x20000, memwidth = 32, romwidth = 32 + files = { ibl_le.b } +} + + diff --git a/src/make/ibl_c661x/ibl_common.inc b/src/make/ibl_c661x/ibl_common.inc new file mode 100644 index 0000000..e7e4c1d --- /dev/null +++ b/src/make/ibl_c661x/ibl_common.inc @@ -0,0 +1,42 @@ +/************************************************************************************ + * FILE PURPOSE: Provide common memory and sections definitions for ibl_init and ibl + ************************************************************************************ + * FILE NAME: ibl_common.inc + * + * DESCRIPTION: Defines the common memory map and section placement required + * to get ibl and ibl_init to work together in a two stage load + * process. + *************************************************************************************/ + +-c +-stack 0x800 +-heap 0x6000 + + +MEMORY +{ + TEXT_INIT : origin = 0x800000, length = 0x2c00 + TEXT : origin = 0x802c00, length = 0xd300 + STACK : origin = 0x810000, length = 0x0800 + HEAP : origin = 0x810800, length = 0x6000 + DATA_INIT : origin = 0x816800, length = 0x0200 + DATA : origin = 0x816a00, length = 0x2e00 + CFG : origin = 0x819800, length = 0x0300 + STAT : origin = 0x819b00, length = 0x0200 + + LINKRAM : origin = 0x10819d00, length = 0x0200 + CPPIRAM : origin = 0x10819f00, length = 0x0200 + PKTRAM : origin = 0x1081a100, length = 0x0800 +} + + +SECTIONS +{ + .stack > STACK + .sysmem > HEAP + + .ibl_config_table > CFG + .ibl_status_table > STAT + +} + diff --git a/src/make/ibl_c661x/ibl_init.cmd b/src/make/ibl_c661x/ibl_init.cmd new file mode 100644 index 0000000..4be6e46 --- /dev/null +++ b/src/make/ibl_c661x/ibl_init.cmd @@ -0,0 +1,31 @@ +/************************************************************************************ + * FILE PURPOSE: Define the memory usage of the ibl module for the c6472 + ************************************************************************************ + * FILE NAME: ibl.cmd + * + * DESCRIPTION: The memory placement for the IBL is defined + * + ************************************************************************************/ + +/* In order to speed build time during debug, the object files are saved in + * both big and little endian format. The include file is generated by + * make to use the correct endian object files + */ +#include "ibl_init_objs.inc" + + +/* Common memory and section areas between ibl_init and ibl */ +#include "ibl_common.inc" + + +SECTIONS +{ + .cinit > TEXT_INIT + .const > TEXT_INIT + .text > TEXT_INIT + .switch > TEXT_INIT + .far > DATA_INIT + .bss > DATA_INIT + +} + diff --git a/src/make/ibl_c661x/ibl_init.rmd b/src/make/ibl_c661x/ibl_init.rmd new file mode 100644 index 0000000..41c1b87 --- /dev/null +++ b/src/make/ibl_c661x/ibl_init.rmd @@ -0,0 +1,11 @@ +-a +-boot +-e _c_int00 + +ROMS +{ + ROM1: org = 0x0400, length = 0x20000, memwidth = 32, romwidth = 32 + files = { ibl_le.b } +} + + diff --git a/src/make/ibl_c661x/ibl_init_image.rmd b/src/make/ibl_c661x/ibl_init_image.rmd new file mode 100644 index 0000000..e137e36 --- /dev/null +++ b/src/make/ibl_c661x/ibl_init_image.rmd @@ -0,0 +1,10 @@ +-a +-e _c_int00 + +ROMS +{ + ROM1: org = 0x800000, length = 0x20000, memwidth = 32, romwidth = 32 + files = { ibl_le.b } +} + + diff --git a/src/make/ibl_c661x/ibl_init_objs_template.inc b/src/make/ibl_c661x/ibl_init_objs_template.inc new file mode 100644 index 0000000..1351d38 --- /dev/null +++ b/src/make/ibl_c661x/ibl_init_objs_template.inc @@ -0,0 +1,22 @@ +/* ibl_init_objs_template.inc + * + * list of object files tagged with the endian field for replacement during make + */ + +../main/c64x/make/iblinit.ENDIAN_TAG.oc +../device/c64x/make/c661xinit.ENDIAN_TAG.oc +../device/c64x/make/c661xutil.ENDIAN_TAG.oc +../device/c64x/make/c64x.ENDIAN_TAG.oa +../hw/c64x/make/pll.ENDIAN_TAG.oc +../hw/c64x/make/cfgpll.ENDIAN_TAG.oc +../hw/c64x/make/cfgpll2.ENDIAN_TAG.oc +../hw/c64x/make/i2c.ENDIAN_TAG.oc +../interp/c64x/make/btblwrap.ENDIAN_TAG.oc +../interp/c64x/make/btblpr.ENDIAN_TAG.oc +../interp/c64x/make/gem.ENDIAN_TAG.oc + + + + + + diff --git a/src/make/ibl_c661x/ibl_objs_template.inc b/src/make/ibl_c661x/ibl_objs_template.inc new file mode 100644 index 0000000..ae2b82e --- /dev/null +++ b/src/make/ibl_c661x/ibl_objs_template.inc @@ -0,0 +1,62 @@ +/* ibl_objs_template.inc + * + * list of oject files tagged with the endian field for replacement during make + */ + +../main/c64x/make/iblmain.ENDIAN_TAG.oc +../device/c64x/make/c661x.ENDIAN_TAG.oc +../device/c64x/make/c661xutil.ENDIAN_TAG.oc +../driver/c64x/make/timer.ENDIAN_TAG.oc +../hw/c64x/make/t64.ENDIAN_TAG.oc +../hw/c64x/make/psc.ENDIAN_TAG.oc +../hw/c64x/make/emif4.ENDIAN_TAG.oc +../device/c64x/make/c64x.ENDIAN_TAG.oa + + +#ifndef EXCLUDE_BIS +../interp/c64x/make/bis.ENDIAN_TAG.oc +#endif + +#ifndef EXCLUDE_COFF +../interp/c64x/make/cload.ENDIAN_TAG.oc +../interp/c64x/make/osal.ENDIAN_TAG.oc +#endif + +#ifndef EXCLUDE_BLOB +../interp/c64x/make/blob.ENDIAN_TAG.oc +#endif + +#ifndef EXCLUDE_ELF +../interp/c64x/make/dload.ENDIAN_TAG.oc +../interp/c64x/make/elfwrap.ENDIAN_TAG.oc +../interp/c64x/make/dlw_client.ENDIAN_TAG.oc +../interp/c64x/make/dload_endian.ENDIAN_TAG.oc +../interp/c64x/make/ArrayList.ENDIAN_TAG.oc +#endif + + +#ifndef EXCLUDE_ETH +../ethboot/c64x/make/ethboot.ENDIAN_TAG.oc +../driver/c64x/make/net.ENDIAN_TAG.oc +../driver/c64x/make/arp.ENDIAN_TAG.oc +../driver/c64x/make/ip.ENDIAN_TAG.oc +../driver/c64x/make/udp.ENDIAN_TAG.oc +../driver/c64x/make/stream.ENDIAN_TAG.oc +../driver/c64x/make/bootp.ENDIAN_TAG.oc +../driver/c64x/make/tftp.ENDIAN_TAG.oc +../hw/c64x/make/mdio.ENDIAN_TAG.oc +../hw/c64x/make/cpsw.ENDIAN_TAG.oc +../hw/c64x/make/qm.ENDIAN_TAG.oc +../hw/c64x/make/cpdma.ENDIAN_TAG.oc +../hw/c64x/make/pa.ENDIAN_TAG.oc +../hw/c64x/make/serdes.ENDIAN_TAG.oc +../hw/c64x/make/sgmii.ENDIAN_TAG.oc +../hw/c64x/make/gmacsl.ENDIAN_TAG.oc +#endif + +#ifndef EXCLUDE_NAND +../nandboot/c64x/make/nandboot.ENDIAN_TAG.oc +../hw/c64x/make/nandemif25.ENDIAN_TAG.oc +../driver/c64x/make/nand.ENDIAN_TAG.oc +../ecc/c64x/make/3byte_ecc.ENDIAN_TAG.oc +#endif diff --git a/src/make/makestg1 b/src/make/makestg1 index 131edd4..be8e5ca 100644 --- a/src/make/makestg1 +++ b/src/make/makestg1 @@ -5,12 +5,12 @@ #* #* DESCRIPTION: Builds the Intermediate Boot Loader (IBL) #* -#* Usage: make c6455 | c6472 | c6474 | c6474l | c6457 [DEBUG=yes] [ETH=no] [NAND=no] \ +#* Usage: make c6455 | c6472 | c6474 | c6457 | c661x [DEBUG=yes] [ETH=no] [NAND=no] \ #* [BIS=no] [COFF=no] [BLOB=no] [ELF=no] [ENDIAN= both | big | little] [I2C_BUS_ADDR= 0x50 | 0x51] \ #* [COMPACT_I2C=yes] [I2C_SIZE_BYTES=..] #******************************************************************************************* -IBLS_C6X= c6455 c6472 c6474 c6474l c6457 +IBLS_C6X= c6455 c6472 c6474 c6474l c6457 c661x # Excluding functions from the build reduces the I2C eeprom memory used and # speeds the initial boot time. Note that boot table cannot be excluded @@ -46,9 +46,11 @@ all: be_target: + make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=big I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) utils make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=big I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) $(TARGET) le_target: + make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=little I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) utils make -f makestg2 ARCH=c64x TARGET=$(TARGET) ENDIAN=little I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) I2C_BUS_ADDR=$(I2C_BUS_ADDR) $(TARGET) compare: diff --git a/src/make/makestg2 b/src/make/makestg2 index 623298d..36d8873 100644 --- a/src/make/makestg2 +++ b/src/make/makestg2 @@ -19,7 +19,7 @@ CLEAN_MODULES=$(addprefix clean_,$(subst hw,,$(MODULES))) CLEAN_MODULES+=$(addprefix clean_,$(CFG_MODULES)) -TARGETS= c6472 c6474 c6474l c6455 c6457 +TARGETS= c6472 c6474 c6474l c6455 c6457 c661x # The main module needs to know the device address of the i2c where the image map resides MAINDEFS=-DIBL_CFG_I2C_MAP_TABLE_DATA_BUS_ADDR=$(I2C_BUS_ADDR) @@ -108,7 +108,7 @@ compare: # For the init code a raw image is created as well as the i2c code to verify # endian independent code is generated. The symbols required for linking # the full application are then extracted -iblInit: $(CFG_MODULES) $(MODULES) utils +iblInit: $(CFG_MODULES) $(MODULES) cat ibl_$(TARGET)/ibl_init_objs_template.inc | sed -e s/ENDIAN_TAG/$(IEXT)/g > ibl_$(TARGET)/ibl_init_objs.inc $(LD) -o ibl_$(TARGET)/ibl_$(TARGET)_init.out -m ibl_$(TARGET)/ibl_$(TARGET)_init.map ibl_$(TARGET)/ibl_init.cmd $(RTLIBS) $(CP) ibl_$(TARGET)/ibl_$(TARGET)_init.out ibl_$(TARGET)/ibl_$(TARGET)_init.$(IEXT).out @@ -154,8 +154,8 @@ utils: make -C $(IBL_ROOT)/util/btoccs make -C $(IBL_ROOT)/util/romparse TARGET=$(TARGET) make -C $(IBL_ROOT)/util/i2cRead TARGET=$(TARGET) $(TARGET) - make -C $(IBL_ROOT)/util/i2cWrite TARGET=$(TARGET) I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) $(TARGET) - make -C $(IBL_ROOT)/util/i2cConfig $(TARGET) + make -C $(IBL_ROOT)/util/i2cWrite TARGET=$(TARGET) I2C_SIZE_BYTES=$(I2C_SIZE_BYTES) MAINDEFS='$(MAINDEFS)' $(TARGET) + make -C $(IBL_ROOT)/util/i2cConfig $(TARGET) MAINDEFS='$(MAINDEFS)' make -C $(IBL_ROOT)/util/bconvert clean: $(CLEAN_MODULES) hwClean diff --git a/src/util/i2cConfig/Makefile b/src/util/i2cConfig/Makefile index 816cbbe..02756da 100644 --- a/src/util/i2cConfig/Makefile +++ b/src/util/i2cConfig/Makefile @@ -43,7 +43,7 @@ #* #*************************************************************** -DEVICES= c6455 c6472 c6474 c6474l c6457 +DEVICES= c6455 c6472 c6474 c6474l c6457 c661x all: @echo must specify a target [ $(DEVICES) ] diff --git a/src/util/i2cConfig/makestg2 b/src/util/i2cConfig/makestg2 index 2cd7450..0443787 100644 --- a/src/util/i2cConfig/makestg2 +++ b/src/util/i2cConfig/makestg2 @@ -7,7 +7,7 @@ #* #************************************************************************** -DEVICES= c6455 c6472 c6474 c6474l c6457 +DEVICES= c6455 c6472 c6474 c6474l c6457 c661x ifndef IBL_ROOT IBL_ROOT=../.. @@ -19,10 +19,28 @@ else IEXT=le endif + +# The PLL object files are device specific +PLL_PATH= ../../hw/c64x/make +ifeq ($(TARGET),c661x) + PLL_OBJS= $(PLL_PATH)/pll.$(IEXT).oc $(PLL_PATH)/cfgpll.$(IEXT).oc $(PLL_PATH)/cfgpll2.$(IEXT).oc +else + PLL_OBJS= $(PLL_PATH)/pll.$(IEXT).oc +endif + +# Device specific helper utilities + + ECODIR= $(IBL_ROOT)/util/i2cConfig +ifeq ($(TARGET),c661x) + TFILES= ../../device/c64x/make/$(TARGET)util.$(IEXT).oc +endif + +MODULES= hw +CFG_MODULES= device -MODULES= hw CLEAN_MODULES=$(addprefix clean_,$(MODULES)) +CLEAN_MODULES+=$(addprefix clean_,$(CFG_MODULES)) CSRC= i2cparam.c @@ -48,13 +66,17 @@ export TARGET .PHONY: i2cparam.cmd -$(DEVICES): gen_cdefdep $(MODULES) $(OBJS) i2cparam.cmd - $(LD) -o i2cparam_$(TARGET)_$(IEXT).out -m i2cparam_$(TARGET)_$(IEXT).map i2cparam.$(IEXT).oc ../../hw/c64x/make/i2c.$(IEXT).oc ../../hw/c64x/make/pll.$(IEXT).oc i2cparam.cmd $(RTLIBS) +$(DEVICES): gen_cdefdep $(MODULES) $(CFG_MODULES) $(OBJS) i2cparam.cmd + $(LD) -o i2cparam_$(TARGET)_$(IEXT).out -m i2cparam_$(TARGET)_$(IEXT).map i2cparam.$(IEXT).oc ../../hw/c64x/make/i2c.$(IEXT).oc $(PLL_OBJS) $(TFILES) i2cparam.cmd $(RTLIBS) $(MODULES): @echo making $@ make -C $(IBL_ROOT)/$@/$(ARCH)/make $@ +$(CFG_MODULES): + @echo making $@ + make -C $(IBL_ROOT)/$@/$(ARCH)/make CDEFS='$(MAINDEFS)' $@ + clean2: $(CLEAN_MODULES) @rm -f $(OBJS) diff --git a/src/util/i2cRead/Makefile b/src/util/i2cRead/Makefile index b23790b..53e70eb 100644 --- a/src/util/i2cRead/Makefile +++ b/src/util/i2cRead/Makefile @@ -42,7 +42,7 @@ #* #*************************************************************** -DEVICES= c6455 c6472 c6474 c6474l c6457 +DEVICES= c6455 c6472 c6474 c6474l c6457 c661x all: @echo must specify a target [ $(DEVICE) ] diff --git a/src/util/i2cRead/makestg2 b/src/util/i2cRead/makestg2 index f0fce5a..ad3e751 100644 --- a/src/util/i2cRead/makestg2 +++ b/src/util/i2cRead/makestg2 @@ -8,7 +8,7 @@ #********************************************************************************* -DEVICES= c6455 c6472 c6474 c6474l c6457 +DEVICES= c6455 c6472 c6474 c6474l c6457 c661x ifndef IBL_ROOT IBL_ROOT=../.. diff --git a/src/util/i2cWrite/Makefile b/src/util/i2cWrite/Makefile index 2bdfc80..ada6822 100644 --- a/src/util/i2cWrite/Makefile +++ b/src/util/i2cWrite/Makefile @@ -42,7 +42,7 @@ #* #*************************************************************** -DEVICES= c6455 c6472 c6474 c6474l c6457 +DEVICES= c6455 c6472 c6474 c6474l c6457 c661x all: @echo must specify a target [ $(DEVICE) ] diff --git a/src/util/i2cWrite/makestg2 b/src/util/i2cWrite/makestg2 index f0921d8..77e3288 100644 --- a/src/util/i2cWrite/makestg2 +++ b/src/util/i2cWrite/makestg2 @@ -8,7 +8,7 @@ #********************************************************************************* -DEVICES= c6455 c6472 c6474 c6474l c6457 +DEVICES= c6455 c6472 c6474 c6474l c6457 c661x ifndef IBL_ROOT IBL_ROOT=../.. @@ -20,10 +20,29 @@ else IEXT=le endif + +# The PLL object files are device specific +PLL_PATH= ../../hw/c64x/make +ifeq ($(TARGET),c661x) + PLL_OBJS= $(PLL_PATH)/pll.$(IEXT).oc $(PLL_PATH)/cfgpll.$(IEXT).oc $(PLL_PATH)/cfgpll2.$(IEXT).oc +else + PLL_OBJS= $(PLL_PATH)/pll.$(IEXT).oc +endif + +ECODIR= $(IBL_ROOT)/util/i2cConfig +ifeq ($(TARGET),c661x) + TFILES= ../../device/c64x/make/$(TARGET)util.$(IEXT).oc +endif + + + ECODIR= $(IBL_ROOT)/util/i2cWrite MODULES= hw +CFG_MODULES= device + CLEAN_MODULES=$(addprefix clean_,$(MODULES)) +CLEAN_MODULES+=$(addprefix clean_,$(CFG_MODULES)) CSRC= i2cWrite.c @@ -47,14 +66,19 @@ export TARGET -$(DEVICES): gen_cdefdep $(MODULES) $(OBJS) i2cWrite.cmd - $(LD) -o i2cWrite_$(IEXT).out -m i2cWrite_$(IEXT).map i2cWrite.$(IEXT).oc ../../hw/c64x/make/i2c.$(IEXT).oc ../../hw/c64x/make/pll.$(IEXT).oc i2cWrite.cmd $(RTLIBS) + +$(DEVICES): gen_cdefdep $(MODULES) $(CFG_MODULES) $(OBJS) i2cWrite.cmd + $(LD) -o i2cWrite_$(IEXT).out -m i2cWrite_$(IEXT).map i2cWrite.$(IEXT).oc ../../hw/c64x/make/i2c.$(IEXT).oc ../../device/c64x/make/$(TARGET)util.$(IEXT).oc $(PLL_OBJS) $(TFILES) i2cWrite.cmd $(RTLIBS) $(MODULES): @echo making $@ make -C $(IBL_ROOT)/$@/$(ARCH)/make $@ +$(CFG_MODULES): + @echo making $@ + make -C $(IBL_ROOT)/$@/$(ARCH)/make CDEFS='$(MAINDEFS)' $@ + clean2: $(CLEAN_MODULES) @rm -f $(OBJS) diff --git a/src/util/romparse/romparse.c b/src/util/romparse/romparse.c index ddcec59..0fd8bcf 100644 --- a/src/util/romparse/romparse.c +++ b/src/util/romparse/romparse.c @@ -474,11 +474,30 @@ void assignKeyVal (int field, int value) case ADDRESS_DELAY: current_table.i2c.address_delay = value; break; -#ifndef c6455 +#if (!defined(c6455) && !defined(c661x)) case SWPLL: current_table.i2c.swPll = value; break; #endif +#ifdef c661x + case SWPLL_PREDIV: current_table.i2c.swPllCfg_lsw &= 0x00ff; + current_table.i2c.swPllCfg_lsw |= ((value & 0xff) << 16); + break; + + case SWPLL_MULT: current_table.i2c.swPllCfg_msw &= 0xc000; + current_table.i2c.swPllCfg_msw |= (value & 0x3fff); + break; + + case SWPLL_POSTDIV: current_table.i2c.swPllCfg_lsw &= 0xff00; + current_table.i2c.swPllCfg_lsw |= (value & 0xff); + break; + + case SWPLL_FLAGS: current_table.i2c.swPllCfg_msw &= 0x3fff; + current_table.i2c.swPllCfg_msw |= ((value & 0x3) << 14); + break; + +#endif + case DEV_ADDR_EXT: current_table.i2c.dev_addr_ext = value; break; diff --git a/src/util/romparse/romparse.h b/src/util/romparse/romparse.h index e7b0fff..58fcf57 100644 --- a/src/util/romparse/romparse.h +++ b/src/util/romparse/romparse.h @@ -56,6 +56,8 @@ #include "tiboot_c6455.h" #elif defined(c6457) #include "tiboot_c6457.h" +#elif defined(c661x) + #include "tiboot_c661x.h" #else #error invalid or missing device specification #endif diff --git a/src/util/romparse/rparse.flex b/src/util/romparse/rparse.flex index 5c7c2bd..bed2a36 100644 --- a/src/util/romparse/rparse.flex +++ b/src/util/romparse/rparse.flex @@ -30,6 +30,10 @@ sw_pll { yylval = SWPLL; return (SWPLL); } align { yylval = ALIGN; return (ALIGN); } len { yylval = LENGTH; return (LENGTH); } pad_file_id { yylval = PAD_FILE_ID; return (PAD_FILE_ID); } +sw_pll_prediv { yylval = SWPLL_PREDIV; return (SWPLL_PREDIV); } +sw_pll_mult { yylval = SWPLL_MULT; return (SWPLL_MULT); } +sw_pll_postdiv { yylval = SWPLL_POSTDIV; return (SWPLL_POSTDIV); } +sw_pll_flags { yylval = SWPLL_FLAGS; return (SWPLL_FLAGS); } [0-9]+ { yylval = atoi(yytext); return (VALUE); } diff --git a/src/util/romparse/rparse.y b/src/util/romparse/rparse.y index df7a25c..9049218 100644 --- a/src/util/romparse/rparse.y +++ b/src/util/romparse/rparse.y @@ -7,6 +7,7 @@ extern char *yytext; %token MULTI_I2C_ID MY_I2C_ID CORE_FREQ_MHZ I2C_CLK_FREQ_KHZ %token EXE_FILE PCI_PARMS NEXT_DEV_ADDR NEXT_DEV_ADDR_EXT ADDRESS_DELAY SWPLL %token DEV_ADDR_EXT DEV_ADDR LAYOUT ALIGN PAD LENGTH PAD_FILE_ID +%token SWPLL_PREDIV SWPLL_MULT SWPLL_POSTDIV SWPLL_FLAGS %% promspec : segment @@ -60,6 +61,10 @@ keyword : BOOT_MODE { $$=$1; } | ALIGN { $$=$1; } | LENGTH { $$=$1; } | PAD_FILE_ID { $$=$1; } + | SWPLL_PREDIV { $$=$1; } + | SWPLL_MULT { $$=$1; } + | SWPLL_POSTDIV { $$=$1; } + | SWPLL_FLAGS { $$=$1; } ; %% -- 2.39.2