UEFI Porting Guide
==================

This document provides instructions for adding support for new Marvell Armada
board. For the sake of simplicity new Marvell board will be called "new_board".

1. Create configuration files for new target
        1.1 Create FDF file for new board

         - Copy and rename edk2-platforms/Platform/Marvell/Armada/Armada70x0.fdf to
           edk2-platforms/Platform/Marvell/Armada/new_board.fdf
         - Change the first no-comment line:
           [FD.Armada70x0_EFI] to [FD.{new_board}_EFI]

        1.2 Create DSC file for new board

         - Add new_board.dsc file to edk2-platforms/Platform/Marvell/Armada directory
         - Insert following [Defines] section to new_board.dsc:

                        [Defines]
                          PLATFORM_NAME                  = {new_board}
                          PLATFORM_GUID                  = {newly_generated_GUID}
                          PLATFORM_VERSION               = 0.1
                          DSC_SPECIFICATION              = 0x00010019
                          OUTPUT_DIRECTORY               = {output_directory}
                          SUPPORTED_ARCHITECTURES        = AARCH64
                          BUILD_TARGETS                  = DEBUG|RELEASE
                          SKUID_IDENTIFIER               = DEFAULT
                          FLASH_DEFINITION               = {path_to_fdf_file}

         - Add "!include Armada.dsc.inc" entry to new_board.dsc

2. Driver support
 - According to content of files from
   edk2-platforms/Silicon/Marvell/Documentation/PortingGuide.txt
   insert PCD entries into new_board.dsc for every needed interface (as listed below).

3. Compilation
 - Refer to edk2-platforms/Platform/Marvell/Readme.md. Remember to change
   {platform} to new_board in order to point build system to newly created DSC file.

4. Output file
 - Output files (and among others FD file, which may be used by ATF) are
   generated under directory pointed by "OUTPUT_DIRECTORY" entry (see point 1.2).

5. ACPI support (optional)
 - The tables can be enabled as in A70x0Db example:

     <path to edk2-platforms>/Platforms/Marvell/Armada/AcpiTables/Armada70x0Db/

 - Enable compilation of the tables in the board's .dsc file. Add it to the
   output flash image contents via .fdf.inc file - path to it defined as
   BOARD_DXE_FV_COMPONENTS. Example:
   Armada70x0Db.dsc:

     BOARD_DXE_FV_COMPONENTS = Platform/Marvell/Armada70x0Db/Armada70x0Db.fdf.inc

     [Components.AARCH64]
       Silicon/Marvell/Armada7k8k/AcpiTables/Armada70x0Db/AcpiTables.inf

   Armada70x0Db.fdf.inc:

     !if $(ARCH) == AARCH64
       # ACPI support
       INF RuleOverride = ACPITABLE Silicon/Marvell/Armada7k8k/AcpiTables/Armada70x0Db/AcpiTables.inf
     !endif


COMPHY configuration
====================
In order to configure ComPhy library, following PCDs are available:

  - gMarvellSiliconTokenSpaceGuid.PcdComPhyDevices

This array indicates, which ones of the ComPhy chips defined in
MVHW_COMPHY_DESC template will be configured.

Every ComPhy PCD has <Num> part where <Num> stands for chip ID (order is not
important, but configuration will be set for first PcdComPhyChipCount chips).

Every chip has 3 ComPhy PCDs and three of them comprise per-board lanes
settings for this chip. Their format is array of up to 10 values reflecting
defined numbers for SPEED/TYPE/INVERT, whose description can be found in:

  OpenPlatformPkg/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h

  - gMarvellSiliconTokenSpaceGuid.PcdChip0ComPhyTypes
        (Array of types - currently supported are:

        CP_UNCONNECTED                      0x0
        CP_PCIE0                            0x1
        CP_PCIE1                            0x2
        CP_PCIE2                            0x3
        CP_PCIE3                            0x4
        CP_SATA0                            0x5
        CP_SATA1                            0x6
        CP_SATA2                            0x7
        CP_SATA3                            0x8
        CP_SGMII0                           0x9
        CP_SGMII1                           0xA
        CP_SGMII2                           0xB
        CP_SGMII3                           0xC
        CP_QSGMII                           0xD
        CP_USB3_HOST0                       0xE
        CP_USB3_HOST1                       0xF
        CP_USB3_DEVICE                      0x10
        CP_XAUI0                            0x11
        CP_XAUI1                            0x12
        CP_XAUI2                            0x13
        CP_XAUI3                            0x14
        CP_RXAUI0                           0x15
        CP_RXAUI1                           0x16
        CP_SFI                              0x17 )

  - gMarvellSiliconTokenSpaceGuid.PcdChip0ComPhySpeeds
        (Array of speeds - currently supported are:

        CP_1_25G                            0x1
        CP_1_5G                             0x2
        CP_2_5G                             0x3
        CP_3G                               0x4
        CP_3_125G                           0x5
        CP_5G                               0x6
        CP_5_15625G                         0x7
        CP_6G                               0x8
        CP_6_25G                            0x9
        CP_10_3125G                         0xA )

  - gMarvellSiliconTokenSpaceGuid.PcdChip0ComPhyInvFlags
        (Array of lane inversion types - currently supported are:

        CP_NO_INVERT                        0x0
        CP_TXD_INVERT                       0x1
        CP_RXD_INVERT                       0x2
        CP_ALL_INVERT                       0x3 )

Example
-------

                  #ComPhy
                  gMarvellSiliconTokenSpaceGuid.PcdComPhyDevices|{ 0x1 }
                  gMarvellSiliconTokenSpaceGuid.PcdChip0ComPhyTypes|{ $(CP_SGMII1), $(CP_USB3_HOST0), $(CP_SFI), $(CP_SATA1), $(CP_USB3_HOST1), $(CP_PCIE2) }
                  gMarvellSiliconTokenSpaceGuid.PcdChip0ComPhySpeeds|{ $(CP_1_25G), $(CP_5G), $(CP_10_3125G), $(CP_5G), $(CP_5G), $(CP_5G) }


PHY Driver configuration
========================
MvPhyDxe provides basic initialization and status routines for Marvell PHYs.
Currently only 1512 and 1112 series PHYs are supported. Following PCDs are required:

  - gMarvellSiliconTokenSpaceGuid.PcdPhyStartupAutoneg
        (boolean - if true, driver waits for autonegotiation on startup)
  - gMarvellSiliconTokenSpaceGuid.PcdPhyDeviceIds
        (list of values corresponding to MV_PHY_DEVICE_ID enum)
  - gMarvellSiliconTokenSpaceGuid.PcdPhySmiAddresses
        (addresses of PHY devices)
  - gMarvellSiliconTokenSpaceGuid.PcdPhy2MdioController
        (Array specifying, which Mdio controller the PHY is attached to)


MV_PHY_DEVICE_ID:

                typedef enum {
                        0    MV_PHY_DEVICE_1512,
                        1    MV_PHY_DEVICE_1112,
                } MV_PHY_DEVICE_ID;

It should be extended when adding support for other PHY models.

Disable autonegotiation:

 gMarvellSiliconTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE

assuming, that PHY models are 1512 and 1112 for two consecutive ports:

 gMarvellSiliconTokenSpaceGuid.PcdPhyDeviceIds|{ 0x0, 0x1 }


MDIO configuration
==================
MDIO driver provides access to network PHYs' registers via EFI_MDIO_READ and
EFI_MDIO_WRITE functions (EFI_MDIO_PROTOCOL). Following PCD is required:

  - gMarvellSiliconTokenSpaceGuid.PcdMdioControllers
        (Array with used controllers
         Set to 0x1 for enabled, 0x0 for disabled)


I2C configuration
=================
In order to enable driver on a new platform, following steps need to be taken:
 - add following line to .dsc file:
   edk2-platforms/Platform/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf
 - add following line to .fdf file:
   INF edk2-platforms/Platform/Marvell/Drivers/I2c/MvI2cDxe/MvI2cDxe.inf
 - add PCDs with relevant values to .dsc file:
        - gMarvellSiliconTokenSpaceGuid.PcdI2cSlaveAddresses|{ 0x50, 0x57 }
                (addresses of I2C slave devices on bus)
        - gMarvellSiliconTokenSpaceGuid.PcdI2cSlaveBuses|{ 0x0, 0x0 }
                (buses to which accoring slaves are attached)
        - gMarvellSiliconTokenSpaceGuid.PcdI2cBusCount|2
                (number of SoC's I2C buses)
        - gMarvellSiliconTokenSpaceGuid.PcdI2cControllersEnabled|{ 0x1, 0x1 }
                (array with used controllers)
        - gMarvellSiliconTokenSpaceGuid.PcdI2cClockFrequency|200000000
                (I2C host controller clock frequency)
        - gMarvellSiliconTokenSpaceGuid.PcdI2cBaudRate|100000
                (baud rate used in I2C transmission)


PciEmulation configuration
==========================
Installation of various NonDiscoverable devices via PciEmulation driver is performed
via set of PCDs. Following are available:

  - gMarvellSiliconTokenSpaceGuid.PcdPciEXhci
        (Indicates, which Xhci devices are used)

  - gMarvellSiliconTokenSpaceGuid.PcdPciEAhci
        (Indicates, which Ahci devices are used)

  - gMarvellSiliconTokenSpaceGuid.PcdPciESdhci
        (Indicates, which Sdhci devices are used)

All above PCD's correspond to hardware description in a dedicated structure:

STATIC PCI_E_PLATFORM_DESC A70x0PlatDescTemplate

in Platform/Marvell/PciEmulation/PciEmulation.c file. It comprises device
count, base addresses, register region size and DMA-coherency type.

Example
-------

Assuming we want to enable second XHCI port and one SDHCI port on Armada
70x0 board, following needs to be declared:

                gMarvellSiliconTokenSpaceGuid.PcdPciEXhci|{ 0x0 0x1 }
                gMarvellSiliconTokenSpaceGuid.PcdPciESdhci|{ 0x1 }


SATA configuration
==================
There is one additional PCD for AHCI:

  - gMarvellSiliconTokenSpaceGuid.PcdSataBaseAddress
        (Base address of SATA controller register space - used in SATA ComPhy init
         sequence)


Pp2Dxe configuration
====================
Pp2Dxe is driver supporting PP2 NIC on Marvell platforms. Following PCDs
are required to operate:

  - gMarvellSiliconTokenSpaceGuid.PcdPp2Controllers
        (Array with used controllers
         Set to 0x1 for enabled, 0x0 for disabled)

  - gMarvellSiliconTokenSpaceGuid.PcdPp2Port2Controller
        (Array specifying, to which controller the port belongs to)

  - gMarvellSiliconTokenSpaceGuid.PcdPp2PhyConnectionTypes
        (Indicates speed of the network interface:

        PHY_RGMII                        0x0
        PHY_RGMII_ID                     0x1
        PHY_RGMII_TXID                   0x2
        PHY_RGMII_RXID                   0x3
        PHY_SGMII                        0x4
        PHY_RTBI                         0x5
        PHY_XAUI                         0x6
        PHY_RXAUI                        0x7
        PHY_SFI                          0x8 )

  - gMarvellSiliconTokenSpaceGuid.PcdPp2PhyIndexes
        (Array specifying, to which PHY from
         gMarvellSiliconTokenSpaceGuid.PcdPhyDeviceIds is used. If none,
         e.g. in 10G SFI in-band link detection, 0xFF value must
         be specified)

  - gMarvellSiliconTokenSpaceGuid.PcdPp2PortIds
        (Identificators of PP2 ports)

  - gMarvellSiliconTokenSpaceGuid.PcdPp2GopIndexes
        (Indexes used in GOP operation)

  - gMarvellSiliconTokenSpaceGuid.PcdPp2InterfaceAlwaysUp
        (Set to 0x1 for always-up interface, 0x0 otherwise)

  - gMarvellSiliconTokenSpaceGuid.PcdPp2InterfaceSpeed
        (Indicates speed of the network interface:

        PHY_SPEED_10                     0x1
        PHY_SPEED_100                    0x2
        PHY_SPEED_1000                   0x3
        PHY_SPEED_2500                   0x4
        PHY_SPEED_10000                  0x5 )


UTMI PHY configuration
======================
In order to configure UTMI, following PCDs are available:

  - gMarvellSiliconTokenSpaceGuid.PcdUtmiControllersEnabled
        (Array with used controllers
         Set to 0x1 for enabled, 0x0 for disabled)

  - gMarvellSiliconTokenSpaceGuid.PcdUtmiPortType
        (Indicates type of the connected USB port:

        UTMI_USB_HOST0                     0x0
        UTMI_USB_HOST1                     0x1
        UTMI_USB_DEVICE0                   0x2 )

Example
-------

                # UtmiPhy
                  gMarvellSiliconTokenSpaceGuid.PcdUtmiControllersEnabled|{ 0x1, 0x1 }
                  gMarvellSiliconTokenSpaceGuid.PcdUtmiPortType|{ $(UTMI_USB_HOST0), $(UTMI_USB_HOST1) }


SPI driver configuration
========================
Following PCDs are available for configuration of spi driver:

  - gMarvellSiliconTokenSpaceGuid.PcdSpiClockFrequency
        (Frequency (in Hz) of SPI clock)

  - gMarvellSiliconTokenSpaceGuid.PcdSpiMaxFrequency
        (Max SCLK line frequency (in Hz) (max transfer frequency) )

SpiFlash configuration
======================
Folowing PCDs for spi flash driver configuration must be set properly:

  - gMarvellSiliconTokenSpaceGuid.PcdSpiFlashMode
        (Default SCLK mode (see SPI_MODE enum in file
         edk2-platforms/Platform/Marvell/Drivers/Spi/MvSpi.h))

  - gMarvellSiliconTokenSpaceGuid.PcdSpiFlashCs
        (Chip select used for communication with the Flash)

MPP configuration
=================
Multi-Purpose Ports (MPP) are configurable through platform PCDs.
In order to set desired pin multiplexing, .dsc file needs to be modified.
(edk2-platforms/Platform/Marvell/Armada/{platform_name}.dsc - please refer to
Documentation/Build.txt for currently supported {platftorm_name} )
Following PCDs are available:

  - gMarvellSiliconTokenSpaceGuid.PcdMppChipCount
        (Indicates how many different chips are placed on board. So far up to 4 chips
         are supported)

Every MPP PCD has <Num> part where
 <Num> stands for chip ID (order is not important, but configuration will be
 set for first PcdMppChipCount chips).

Below is example for the first chip (Chip0).

  - gMarvellSiliconTokenSpaceGuid.PcdChip0MppReverseFlag
        (Indicates that register order is reversed. (Needs to be used only for AP806-Z1) )

  - gMarvellSiliconTokenSpaceGuid.PcdChip0MppBaseAddress
        (This is base address for MPP configuration register)

  - gMarvellSiliconTokenSpaceGuid.PcdChip0MppPinCount
        (Defines how many MPP pins are available)

  - gMarvellSiliconTokenSpaceGuid.PcdChip0MppSel0
  - gMarvellSiliconTokenSpaceGuid.PcdChip0MppSel1
  - gMarvellSiliconTokenSpaceGuid.PcdChip0MppSel2
        (This registers defines functions of 10 pins in ascending order)

Examples
--------

                # APN806-A0 MPP SET
                 gMarvellSiliconTokenSpaceGuid.PcdChip0MppReverseFlag|FALSE
                 gMarvellSiliconTokenSpaceGuid.PcdChip0MppBaseAddress|0xF06F4000
                 gMarvellSiliconTokenSpaceGuid.PcdChip0MppRegCount|3
                 gMarvellSiliconTokenSpaceGuid.PcdChip0MppSel0|{ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0 }
                 gMarvellSiliconTokenSpaceGuid.PcdChip0MppSel1|{ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }

Set pin 6 and 7 to 0xa function:
                 gMarvellSiliconTokenSpaceGuid.PcdChip0MppSel0|{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0x0, 0x0 }


Ramdisk configuration
=====================
There is one PCD available for Ramdisk configuration

  - gMarvellSiliconTokenSpaceGuid.PcdRamDiskSize
        (Defines size of Ramdisk)
