1. Introduction
---------------
**SpiDxe** driver implements MARVELL_SPI_MASTER_PROTOCOL in order to manage SPI
controller on Marvell A8k boards. It exposes below functionalities:
 - create and setup SPI slaves
 - raw transfer over SPI bus

2. SpiDxe driver design
-----------------------

  2.1 MARVELL_SPI_MASTER_PROTOCOL
  -----------------------
  First member of SPI_MASTER protocol is Init function, implemented for SPI
  master controller initialization.

  ->Init()

    //
    //Initializes the host controller to execute SPI commands.
    //

    param[IN]   This Pointer to the MARVELL_SPI_MASTER_PROTOCOL instance

    return      EFI_SUCCESS             Opcode initialization on the SPI host
                                        controller completed.
    return      EFI_ACCESS_DENIED       The SPI configuration interface is
                                        locked.
    return      EFI_OUT_OF_RESOURCES    Not enough resource available to
                                        initialize the device.
    return      EFI_DEVICE_ERROR        Device error, operation failed.

  ********

  SPI devices (slaves) do not support any kind of automatic discovery or
  enumaration, so every device needs manual configuration, which may be done
  with SetupDevice function.

    ->SetupDevice()

    //
    //Allocate and zero all fields in the SPI_DEVICE struct. Set the chip
    //select, max frequency and transfer mode supported by slave device.
    //

    param[IN]   Cs Chip select ID of the slave chip.
    param[IN]   MaxFreq Maximum SCK rate in Hz.
    param[IN]   Mode Clock polarity and clock phase.

    return      *SPI_DEVICE   Pointer to new allocated struct SPI_DEVICE.
    return      NULL          NULL pointer if any eroor occured.

    ********

  Developers have to destroy all created SPI device structs (with FreeDevice
  function) in order to prevent from memory leak.

    ->FreeDevice()

    //
    //Free any memory associated with a SPI device.
    //

    param[in]   SpiDev                  Pointer to the SPI_DEVICE struct.

    return      EFI_SUCCESS             Memory fried succesfully.
    return      EFI_DEVICE_ERROR        Device error, operation failed.

    ********

  Transfer function allows write/read raw bytes over SPI bus.

    ->Transfer()

    //
    //Perform transfer over SPI bus
    //
    param[in]     This                  Pointer to the MARVELL_SPI_MASTER_PROTOCOL
                                        instance.
    param[in]     Slave                 Pointer to the SPI_DEVICE struct.
    param[in]     DataByteCount         Number of bytes in the data portion of
                                        the SPI cycle.
    param[in]     DataOut               Pointer to caller-allocated buffer
                                        containing the data to send.
    param[out]    DataIn                Pointer to caller-allocated buffer
                                        where received data will be placed.
    param[in]     Flag                  Flags which indicate state of CS line
                                        during/after transfer (see file
                                        Drivers/Spi/Devices/A8kSpiFlash.h)

    return        EFI_SUCCESS           Memory fried succesfully.
    return        EFI_DEVICE_ERROR      Device error, operation failed.

    *********

  When working with SPI devices it is often necessary to perform "command and
  address" transactions. It may be done via ReadWrite function.

    ->ReadWrite()

    //
    //Perform two steps transactions. First write Command, then read/write
    //buffer
    //

    param[in]     This                  Pointer to the MARVELL_SPI_MASTER_PROTOCOL
                                        instance.
    param[in]     Slave                 Pointer to the SPI_DEVICE struct.
    param[in]     Cmd                   Pointer to caller-allocated buffer
                                        containing the command to send.
    param[in]     CmdSize               Size of command (in bytes).
    param[in]     DataOut               Pointer to caller-allocated buffer
                                        containing the data to send.
    param[out]    DataIn                Pointer to caller-allocated buffer
                                        where received data will be placed.
    param[in]     DataSize              Number of bytes in the data portion of
                                        the SPI cycle.