-
Notifications
You must be signed in to change notification settings - Fork 77
Porting Hardware Adaptation Layer
The ARMADA 39x and ARMADA 38x SoCs share the same HAL code, under the ARMADA 38x family. Board-level and low-level hardware functionality can be implemented in the Hardware Abstraction Layer (HAL). U-Boot files are located in board/mv_ebu/a38x/armada_38x_family. Linux files are located in arch/arm/mach-armada38x/armada_38x_family.
NOTE: HAL files are not relevant for Linux 3.10 (see Wiki "Linux Porting" in the repository linux-armada38x: Linux Porting Guide).
MPP Configuration Each of the MPPs is described by 4 bits. There are 8 MPP values in a group, one value for each MPP register. To set a certain MPP as GPIO, set its corresponding bit value as 0x0. The MPP configuration is defined in the mvBoardEnvSpec38x.h that is found under the board/mv_ebu/a38x/armada_38x_family/boardEnv.
The ARMADA 38x customer board #0 uses the following MPP configuration:
#define A38x_CUSTOMER_BOARD_0_MPP0_7 0x11111111 #define A38x_CUSTOMER_BOARD_0_MPP8_15 0x11111111 #define A38x_CUSTOMER_BOARD_0_MPP16_23 0x11266011 #define A38x_CUSTOMER_BOARD_0_MPP24_31 0x22222011 #define A38x_CUSTOMER_BOARD_0_MPP32_39 0x22200002 #define A38x_CUSTOMER_BOARD_0_MPP40_47 0x40042022 #define A38x_CUSTOMER_BOARD_0_MPP48_55 0x55550555 #define A38x_CUSTOMER_BOARD_0_MPP56_63 0x00005550
In this example, the fourth MPP set (MPP24_31) is configured to: MPP24-26 = 0x1, MPP27-31 = 0x2.
To set a certain MPP as GPIO, set its corresponding MPP bit value to 0x0.
The GPIO configuration set is divided into 2 groups - Low and Medium. Each represents a bitmap of 32-bit GPIOs. In the mvBoardEnvSpec38x.h files, which is located under the board/mv_ebu/a38x/armada_38x_family/boardEnv, configure the GPIO as either output or input state, and set the output value and polarity of every pin. The defined values modify the matching GPIO Data Out, Data Out Enable Control, and Data In Polarity registers:
-
GPIO Output Enable: to enable Data Out GPIO, set its corresponding bit to ‘0’ in the GPP_OUT_ENA parameter (‘1’ indicating input GPIO input)
-
GPIO Data out value: relevant only if GPIO is set to output, and its value is selected in the GPP_OUT_VAL parameter
-
GPIO input Polarity: relevant only if GPIO is set to input, and set in the GPP_POL parameter: ‘1’ – active low ‘0’ – active high.
The ARMADA 38x customer board #0 uses the following GPIO configuration:
#define A38x_CUSTOMER_BOARD_0_GPP_OUT_ENA_LOW (~(BIT1 | BIT4 | BIT6 | BIT7 | BIT8 | BIT9 | BIT10 | \
BIT11 | BIT19 | BIT20 | BIT22 | BIT23 | BIT25 | BIT26 | \
BIT27 | BIT29 | BIT30 | BIT31))
#define A38x_CUSTOMER_BOARD_0_GPP_OUT_ENA_MID (~(BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT15 | BIT16 |\
BIT17 | BIT18))
#define A38x_CUSTOMER_BOARD_0_GPP_OUT_VAL_LOW (~(BIT1 | BIT4 | BIT6 | BIT7 | BIT8 | BIT9 | BIT10 | \
BIT11 | BIT19 | BIT22 | BIT23 | BIT25 | BIT26 | \
BIT27 | BIT29 | BIT30 | BIT31))
#define A38x_CUSTOMER_BOARD_0_GPP_OUT_VAL_MID 0x0
#define A38x_CUSTOMER_BOARD_0_GPP_POL_LOW 0x0
#define A38x_CUSTOMER_BOARD_0_GPP_POL_MI 0x0
In the above example, GPIOs 1,4,6-11,19,29,22,23,25,and 26 are set to output (in OUT_ENA_LOW) with value 1 (in OUT_VAL_LOW).
The board configuration specific structures are defined for each supported board in the MV_BOARD_INFO structure and are located in board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvSpec38x.c.
Both customer boards use the board structure armada_38x_customer_board_0_Info. To support a second customer board, duplicate the armada_38x_customer_board_0_Info struct, customize it according to board specification, and set it as the second entry of the array customerBoardInfoTbl (replace it with the second entry of armada_38x_customer_board_0_Info).
The MV_BOARD_INFO structure includes the following relevant fields:
Table: MV_BOARD_INFO Structure
| Field | Description |
|---|---|
boardName |
String for board name |
pBoardMppConfigValue |
MPP configuration struct (see Section MPP Configuration for details) |
pDevCsInfo |
Device bus / NAND controller configuration struct (see Section NOR and SPI Configuration for details) |
pBoardTwsiDev |
Struct describing I2C devices on the board (see Section I2C Configuration for details) |
pBoardMacInfo |
Struct describing Ethernet PHY / Switch speed and Serial Management Interface (SMI) addresses (see Section PHY Configuration for details) |
configAutoDetect |
Boolean indicating if board utilizes configuration auto-detection sequence. Must set to MV_FALSE for customer static configuration. |
pBoardUsbInfo |
Struct describing USB mapping per board (see Section USB Mapping for details) |
numBoardUsbInfo |
Number of USB devices in pBoardUsbInfo structure. |
NOTE: Marvell recommends initializing board-related information that is not included in the board specification in the mvBoardEnvInit() function located in the board/mv_ebu/a38x/armada_38x_family/boardEnv/mvBoardEnvLib.c which initializes the board environment.
The following fields, specified in the MV_BOARD_INFO board specification structure. is used in the initialization process:
Table: MV_BOARD_INFO Board Initialization
| Field | Description |
|---|---|
gppOutEnValLow/Mid/ |
2*32Bit values describing GPIO output enabled pins |
gppOutValLow/Mid/ |
2*32Bit values describing GPIO output enabled values |
gppPolarityLow/Mid/ |
2*32Bit values describing GPIO input polarity settings |
nandFlashRead/WriteParams and nandFlashControl |
NAND interface access configuration parameters |
norFlashRead/WriteParams |
NOR interface access configuration parameters |
NOTE: Some MV_BOARD_INFO fields were not described in the above table, because they are not relevant for the customer porting process and must not be modified.
To configure the I2C device definition, update the MV_BOARD_TWSI_INFO structure or place NULL in the pointer location in the board information structure.
Table: MV_BOARD_TWSI_INFO I2C Configuration
| Field | Description |
|---|---|
devClass |
Device class (RTC, EXP, SATR…) |
devClassId |
Device Number (for similar device class) |
twsiDevAddr |
I2C address |
twsiDevAddrType |
Address type 7-bit or 10-bit addressing (ADDR7_BIT or ADDR10_BIT) |
moreThen256 |
Boolean to indicate required address size for TWSI device |
In the following example, I2C devices are defined to:
-
Sample At Reset I2C devices with 7-bit address type are located at 0x50 and 0x4C, respectively.
-
An IO Expander I2C device with 7-bit address type is located at 0x20 and 0x21, respectively.
MV_BOARD_TWSI_INFO armada_38x_customer_0_BoardTwsiDev[] = {
/* {{MV_BOARD_DEV_CLASS devClass, MV_U8 devClassId,MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}}*/
{ BOARD_DEV_TWSI_SATR, 0, 0x50, ADDR7_BIT, MV_TRUE}, /* read only for HW configuration */
{ BOARD_DEV_TWSI_SATR, 1, 0x4C, ADDR7_BIT, MV_FALSE},
{ BOARD_TWSI_IO_EXPANDER, 0, 0x20, ADDR7_BIT, MV_FALSE},
{ BOARD_TWSI_IO_EXPANDER, 1, 0x21, ADDR7_BIT, MV_FALSE},
};
NOTE: The PHY configuration setup must correspond to the PHY devices initialized. See section Adding Support for a New PHY Device in the "Porting U-Boot" Wiki.
The PHY specification is defined in the MV_BOARD_MAC_INFO structure in the file mvBoardEnvLib.h
in mvBoardEnvLib38x.h :
typedef struct _boardMacInfo {
MV_BOARD_MAC_SPEED boardMacSpeed;
MV_32 boardEthSmiAddr;
MV_32 boardEthSmiAddr0;
MV_BOOL boardMacEnabled;
} MV_BOARD_MAC_INFO;
The order of the cells in the array corresponds to the order of the physical GbE ports. Update the PHY device definition structure or place NULL in the pointer location in the board information structure.
The table below describes a possible configuration of the PHY configuration fields.
Table: PHY Configuration Fields
| Field | Description |
|---|---|
boardMacSpeed |
Speed capabilities (10M, 100M, 1000M, 2000M or auto) |
boardEthSmiAddr |
PHY device located at the SMI address (-1 if the MAC is not connected to PHY, or in case of InBand Auto negotiation and SGMII) |
boardEthSmiAddr0 |
For QUAD PHY usage only: PHY initialization address of the QUAD PHY |
boardMacEnabled |
Enable status of the GbE port. A port is considered to be connected only if it is enabled, identified as R/SGMII and has valid MAC info entry |
In the following example:
-
PHY device located at SMI address 0x0 with auto-speed capabilities is connected to GbE#0
-
PHY device located at SMI address 0x1 with auto-speed capabilities is connected to GbE#1.
MV_BOARD_MAC_INFO armada_38x_customer_board_0_InfoBoardMacInfo[] =
{
{BOARD_MAC_SPEED_AUTO, 0x0, 0x0, MV_TRUE}
{BOARD_MAC_SPEED_AUTO, 0x1, 0x1, MV_TRUE},
};
NOTE: When modifying the PHY configuration, an adequate PHY initialization sequence must be used. The PHY initialization sequence is set in routine mvBoardEgigaPhyInit() in file board/mv_ebu/common/USP/mv_phy.c.
For NOR and SPI configuration, update the MV_DEV_CS_INFO structures or place NULL in the pointer location in the board information structure.
Table MV_DEV_CS_INFO Parameters describes the MV_DEV_CS_INFO structure parameters.
Table: MV_DEV_CS_INFO Parameters
| Field | Description | Options |
|---|---|---|
deviceCS |
Device chip select |
|
params |
Not in use, for debug purposes only |
|
devClass |
Device class |
* BOARD_DEV_NOR_FLASH * BOARD_DEV_NAND_FLASH * BOARD_DEV_SEVEN_SEG * BOARD_DEV_FPGA * BOARD_DEV_SRAM * BOARD_DEV_SPI_FLASH * BOARD_DEV_OTHER |
devWidth |
Device width |
* 8 * 16 * 32 |
busWidth |
Bus width |
* 8 * 16 * 32 |
busNum |
Unit bus number |
|
active |
Boolean indicating unit status (MV_TRUE/MV_FALSE) |
Table Board Flash Devices Configuration Example describes a sample configuration of a board with two Flash devices.
Table: Board Flash Devices Configuration Example
| Flash Device | Connection | Details |
|---|---|---|
SPI Flash |
Device chip select |
* Device class: BOARD_DEV_SPI_FLASH * Device width: 8 * Bus width: 8 |
Second Flash |
NOR connected to the MV_BOOTCS chip select |
* Device class: BOARD_DEV_NOR_FLASH * Device width: 16 * Bus width: 16 |
The following code describes how to configure the state described in the Table Board Flash Devices Configuration Example:
MV_DEV_CS_INFO armada_38x(or armada_39x)_customerInfoBoardDeCsInfo[] = {
/*{deviceCS, params, devType, devWidth, busWidth, busNum, active }*/
{ DEV_BOOCS, N_A, BOARD_DEV_NAND_FLASH, 16, 16, 0, MV_FALSE }, /* NAND DEV */
{ DEVICE_CS0, N_A, BOARD_DEV_NAND_FLASH, 16, 16, 0, MV_FALSE }, /* NAND DEV */
{ DEVICE_CS1, N_A, BOARD_DEV_NAND_FLASH, 16, 16, 0, MV_FALSE }, /* NAND DEV */
{ DEVICE_CS2, N_A, BOARD_DEV_NAND_FLASH, 16, 16, 0, MV_FALSE }, /* NAND DEV */
{ DEVICE_CS3, N_A, BOARD_DEV_NAND_FLASH, 16, 16, 0, MV_FALSE }, /* NAND DEV */
{ DEV_BOOCS, N_A, BOARD_DEV_NOR_FLASH, 16, 16, 0, MV_FALSE }, /* NOR DEV */
{ SPI_CS0, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_TRUE }, /* SPI DEV */
{ SPI_CS1, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_FALSE }, /* SPI DEV */
{ SPI_CS2, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_FALSE }, /* SPI DEV */
{ SPI_CS3, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_FALSE }, /* SPI DEV */
{ SPI_CS4, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_FALSE }, /* SPI DEV */
{ SPI_CS5, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_FALSE }, /* SPI DEV */
{ SPI_CS6, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_FALSE }, /* SPI DEV */
{ SPI_CS7, N_A, BOARD_DEV_SPI_FLASH, 8, 8, 0, MV_FALSE } /* SPI DEV */
}
To enable CPSS Switching Services commands, enable the isAmc entry in the board structure, in the mvBoardEnvSpec38x.c file, as shown below:
.isAmc = MV_TRUE
To configure the USB mapping to board, update the MV_BOARD_USB structure or place NULL in the pointer location in the board information structure.
The following table MV_BOARD_USB Structure USB Mapping describes the MV_BOARD_USB structure definition:
Table: MV_BOARD_USB Structure USB Mapping
| Field | Description |
|---|---|
MV_UNIT_ID usbType |
USB type(USB3_UNIT_ID,USB_UNIT_ID) |
MV_U8 usbPortNum |
USB port number |
MV_BOOL isActive |
boolean variable, true if USB is active on the board |
The environment variable usbActive now represents the USB host hardware number (i.e: for USB3.0 Host 1, always use usbActive=1).
The following is an example of how to declare a MV_BOARD_USB structure to a specific board, in which USB port 1 is active as a USB 3.0 port:
MV_BOARD_USB_INFO armada_38x_customer_0_InfoBoardUsbInfo[] = {
/* {MV_UNIT_ID usbType, MV_U8 usbPortNum, MV_BOOL isActive} */
{ USB3_UNIT_ID, 0, MV_TRUE},
{ USB3_UNIT_ID, 1, MV_TRUE},
{ USB_UNIT_ID, 0, MV_TRUE},
};
To configure the SOHO Switch definition, update the MV_BOARD_SWITCH_INFO structure according to the following, or place NULL in the pointer (pSwitchInfo) in location in the board information structure. For the Linux configuration, see Section "SOHO Switch" on Linux Porting Guide of the linux-armada38x repository: Linux Porting Guide - SOHO Switch
The following table describes the MV_BOARD_SWITCH_INFO structure definition:
Table: MV_BOARD_SWITCH_INFO Structure for SOHO Configuration for ARMADA 38x
| Field | Description | Possible Values |
|---|---|---|
isEnabled |
Is switch enabled |
MV_TRUE / MV_FALSE |
switchIrq |
PPU/IRQ |
-1 if PPU mode / else IRQ number |
switchPort |
Available switch ports mapping |
0..n (n max switch port number) |
cpuPort |
Single switch CPU port |
0..n (n max switch port number) |
connectedPort |
Defines which SoC ETH unit mapping per switch port |
0,1,2 (ETH unit numbers) |
smiScanMode |
Switch device scan mode |
MV_SWITCH_SMI_AUTO_SCAN_MODE MV_SWITCH_SMI_MANUAL_MODE MV_SWITCH_SMI_MULTI_ADDR_MODE |
quadPhyAddr |
Switch SMI address |
0x0..0xFF |
forceLinkMask |
Force link ports mask |
Hexadecimal bit mask for forced link ports |
isCpuPortRgmii |
Whether switch is connected to RGMII-phy |
MV_TRUE / MV_FALSE |
The configuration described above is used in the following example:
-
switchIrq: Using PPU but not IRQ,
-
switchPort : Using 7 switch ports P0-P6
-
cpuPort: Switch CPU port is 6
-
connectedPort: eth0 connects to Switch P5 and eth1 connects to Switch P6
-
smiScanMode: Switch access mode is SMI multi-address mode
-
quadPhyAddr: Switch SMI address is 2
-
forceLinkMask: Force link switch ports are P5 and P6
struct MV_BOARD_SWITCH_INFO db88f68xxSwitchInfo[] = {
{
.isEnabled = MV_FALSE,
.isCpuPortRgmii = MV_TRUE,
.switchIrq = -1, /* set to -1 for using PPU*/
.switchPort = {0, 1, 2, 3, 4, 5, 6},
.cpuPort = 6,
.connectedPort = {5, 6, -1},
.smiScanMode = MV_SWITCH_SMI_MULTI_ADDR_MODE,
.quadPhyAddr = 2,
.forceLinkMask = 0x60
}
};
Special GPIO pull-up/down flow required after board initialization, can be implemented in a pre-defined GPIO callback routine, which is called as the final step of mvBoardEnvInit() flow.
void A38x_CUSTOMER_BOARD_0_gpp_callback(MV_BOARD_INFO *board)
{
/* Implement special GPIO/MPP post configuration here */
}
For example, use SolidRun’s ClearFog GPIO callback implementation as reference: In this example, the following was implemented:
-
Post board configuration toggle of GPIO41, to reset Switch and PHY on their board.
-
Update IO expander values for special IO unit configuration
void A38x_CLEARFOG_BOARD_gpp_callback(MV_BOARD_INFO *board) {
/* Toggle GPIO41 to reset on-board switch and phy */
/* Set GPIO41 as output enabled */
MV_REG_BIT_RESET (GPP_DATA_OUT_REG(1), BIT9);
/* Reset output value */
MV_REG_BIT_RESET (GPP_DATA_OUT_EN_REG(1), BIT9);
/* Set output value */
mvOsDelay(1);
MV_REG_BIT_SET (GPP_DATA_OUT_EN_REG(1), BIT9);
mvOsDelay(10);
/* Update on-board IO expander with pre-defined values:
* USB3 current limiter, and SFP_TX_DIS, deassert and assert 2*mini PCIe reset signals, */
mvBoardIoExpanderUpdate();
}
NOTE: This section is optional only, and can also be used for other required board post-configuration.
To configure the GPP, update the MV_BOARD_GPP_INFO structure according to the following, or place NULL in the pointers: pBoardGppInfo and numBoardGppInfo in the board information structure.
Table: MV_BOARD_GPP_INFO Structure for GPP Configuration
| Field | Description | Comment |
|---|---|---|
devClass |
Device class |
RTC, MV_SWITCH, USB_VBUS, …). See MV_BOARD_GPP_CLASS to see the full list |
gppPinNum |
Relevant GPP pin |
-1 if PPU mode / else IRQ number |
Example:
To configure the MPP, do the following for USB3 VBUS:
MV_BOARD_GPP_INFO armada_38x_customer_0_GppInfo[] =
{
/* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
/* USB_Host0 */ {BOARD_GPP_USB_VBUS, 44}, /* from MPP map */
};
According to the USB3 standard, when a USB3 device detects Power On Reset or Warm Reset, it starts the Link Training process. After power up or board reset, the USB3 device starts the Link Training process. Since the USB SERDES of the Marvell SoC is not initialized, the USB3 device might end the link negotiation as HS (USB2) and not SS (USB3). To overcome this issue, the device VBUS is controlled by connecting one of the SoC MPPs to the current-limiter enable pin. Ensure that the default configuration of the current-limit device is disabled during reset so that the VBUS is off. This connectivity enables the software to control the enabling of the current-limit device and turn on the VBUS. The software controls the VBUS power on/off of the USB device. The Marvell SDK implements this method on both U-boot and Linux. For more details refer to TB-335: USB VBUS Control. To configure the MPP, refer to the GPP Configuration section.