Argh, slipped on the reviewed-by....
Exported function/struct names Efi* sound like they were implementations of core specification protocol. Unless I've missed something and they are, I would much prefere for them to be Mv*.
If you can fix that before you add the reviewed-by :)
On Fri, Apr 29, 2016 at 07:26:02PM +0200, Marcin Wojtas wrote:
From: Jan Dąbroś jsd@semihalf.com
Spi master driver implements MARVELL_SPI_MASTER_PROTOCOL. It configures and manages SPI controller.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Documentation/Marvell/Drivers/SpiDriver.txt | 116 +++++++++ Documentation/Marvell/PortingGuide/Spi.txt | 15 ++ Drivers/Spi/MvSpiDxe.c | 378 ++++++++++++++++++++++++++++ Drivers/Spi/MvSpiDxe.h | 145 +++++++++++ Drivers/Spi/MvSpiDxe.inf | 66 +++++ Platforms/Marvell/Marvell.dec | 5 + 6 files changed, 725 insertions(+) create mode 100644 Documentation/Marvell/Drivers/SpiDriver.txt create mode 100644 Documentation/Marvell/PortingGuide/Spi.txt create mode 100644 Drivers/Spi/MvSpiDxe.c create mode 100644 Drivers/Spi/MvSpiDxe.h create mode 100644 Drivers/Spi/MvSpiDxe.inf
diff --git a/Documentation/Marvell/Drivers/SpiDriver.txt b/Documentation/Marvell/Drivers/SpiDriver.txt new file mode 100644 index 0000000..42b5e3c --- /dev/null +++ b/Documentation/Marvell/Drivers/SpiDriver.txt @@ -0,0 +1,116 @@ +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 fileDrivers/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.diff --git a/Documentation/Marvell/PortingGuide/Spi.txt b/Documentation/Marvell/PortingGuide/Spi.txt new file mode 100644 index 0000000..f1f36ad --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Spi.txt @@ -0,0 +1,15 @@ +Spi driver configuration +------------------------ +Following PCDs are available for configuration of spi driver:
- gMarvellTokenSpaceGuid.PcdSpiClockFrequency
 +Frequency (in Hz) of SPI clock
- gMarvellTokenSpaceGuid.PcdSpiMaxFrequency
 +Max SCLK line frequency (in Hz) (max transfer frequency)
- gMarvellTokenSpaceGuid.PcdSpiDefaultMode
 +default SCLK mode (see SPI_MODE enum in file OpenPlatformPkg/Drivers/Spi/MvSpi.h) diff --git a/Drivers/Spi/MvSpiDxe.c b/Drivers/Spi/MvSpiDxe.c new file mode 100644 index 0000000..1bdb9ed --- /dev/null +++ b/Drivers/Spi/MvSpiDxe.c @@ -0,0 +1,378 @@ +/******************************************************************************* +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +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 Marvell 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 "MvSpiDxe.h"
+SPI_MASTER *mSpiMasterInstance;
+STATIC +EFI_STATUS +SpiSetBaudRate (
- IN UINT32 CpuClock,
 - IN UINT32 MaxFreq
 - )
 +{
- UINT32 Spr, BestSpr, Sppr, BestSppr, ClockDivider, Match, Reg, MinBaudDiff;
 - UINTN SpiRegBase = PcdGet32 (PcdSpiRegBase);
 - MinBaudDiff = 0xFFFFFFFF;
 - BestSppr = 0;
 - //Spr is in range 1-15 and Sppr in range 0-8
 - for (Spr = 1; Spr <= 15; Spr++) {
 - for (Sppr = 0; Sppr <= 7; Sppr++) {
 ClockDivider = Spr * (1 << Sppr);if ((CpuClock / ClockDivider) > MaxFreq) {continue;}if ((CpuClock / ClockDivider) == MaxFreq) {BestSpr = Spr;BestSppr = Sppr;Match = 1;break;}if ((MaxFreq - (CpuClock / ClockDivider)) < MinBaudDiff) {MinBaudDiff = (MaxFreq - (CpuClock / ClockDivider));BestSpr = Spr;BestSppr = Sppr;}- }
 - if (Match == 1) {
 break;- }
 - }
 - if (BestSpr == 0) {
 - return (EFI_INVALID_PARAMETER);
 - }
 - Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG);
 - Reg &= ~(SPI_SPR_MASK | SPI_SPPR_0_MASK | SPI_SPPR_HI_MASK);
 - Reg |= (BestSpr << SPI_SPR_OFFSET) |
 ((BestSppr & 0x1) << SPI_SPPR_0_OFFSET) |((BestSppr >> 1) << SPI_SPPR_HI_OFFSET);- MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg);
 - return EFI_SUCCESS;
 +}
+STATIC +VOID +SpiSetCs (
- UINT8 CsId
 - )
 +{
- UINT32 Reg, SpiRegBase = PcdGet32 (PcdSpiRegBase);
 - Reg = MmioRead32 (SpiRegBase + SPI_CTRL_REG);
 - Reg &= ~SPI_CS_NUM_MASK;
 - Reg |= (CsId << SPI_CS_NUM_OFFSET);
 - MmioWrite32 (SpiRegBase + SPI_CTRL_REG, Reg);
 +}
+STATIC +VOID +SpiActivateCs (
- UINT8 IN CsId
 - )
 +{
- UINT32 Reg, SpiRegBase = PcdGet32 (PcdSpiRegBase);
 - SpiSetCs(CsId);
 - Reg = MmioRead32 (SpiRegBase + SPI_CTRL_REG);
 - Reg |= SPI_CS_EN_MASK;
 - MmioWrite32(SpiRegBase + SPI_CTRL_REG, Reg);
 +}
+STATIC +VOID +SpiDeactivateCs (
- VOID
 - )
 +{
- UINT32 Reg, SpiRegBase = PcdGet32 (PcdSpiRegBase);
 - Reg = MmioRead32 (SpiRegBase + SPI_CTRL_REG);
 - Reg &= ~SPI_CS_EN_MASK;
 - MmioWrite32(SpiRegBase + SPI_CTRL_REG, Reg);
 +}
+STATIC +VOID +SpiSetupTransfer (
- IN MARVELL_SPI_MASTER_PROTOCOL *This,
 - IN SPI_DEVICE *Slave
 - )
 +{
- SPI_MASTER *SpiMaster;
 - UINT32 Reg, SpiRegBase, CoreClock, SpiMaxFreq;
 - SpiMaster = SPI_MASTER_FROM_SPI_MASTER_PROTOCOL (This);
 - // Initialize values from PCDs
 - SpiRegBase = PcdGet32 (PcdSpiRegBase);
 - CoreClock = PcdGet32 (PcdSpiClockFrequency);
 - SpiMaxFreq = PcdGet32 (PcdSpiMaxFrequency);
 - EfiAcquireLock (&SpiMaster->Lock);
 - Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG);
 - Reg |= SPI_BYTE_LENGTH;
 - MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg);
 - SpiSetCs(Slave->Cs);
 - SpiSetBaudRate (CoreClock, SpiMaxFreq);
 - Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG);
 - Reg &= ~(SPI_CPOL_MASK | SPI_CPHA_MASK | SPI_TXLSBF_MASK | SPI_RXLSBF_MASK);
 - switch (Slave->Mode) {
 - case SPI_MODE0:
 - break;
 - case SPI_MODE1:
 - Reg |= SPI_CPHA_MASK;
 - break;
 - case SPI_MODE2:
 - Reg |= SPI_CPOL_MASK;
 - break;
 - case SPI_MODE3:
 - Reg |= SPI_CPOL_MASK;
 - Reg |= SPI_CPHA_MASK;
 - break;
 - }
 - MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg);
 - EfiReleaseLock (&SpiMaster->Lock);
 +}
+EFI_STATUS +EFIAPI +EfiSpiTransfer (
- IN MARVELL_SPI_MASTER_PROTOCOL *This,
 - IN SPI_DEVICE *Slave,
 - IN UINTN DataByteCount,
 - IN VOID *DataOut,
 - IN VOID *DataIn,
 - IN UINTN Flag
 - )
 +{
- SPI_MASTER *SpiMaster;
 - UINT64 Length;
 - UINT32 Iterator, Reg, SpiRegBase;
 - UINT8 *DataOutPtr = (UINT8 *)DataOut;
 - UINT8 *DataInPtr = (UINT8 *)DataIn;
 - UINT8 DataToSend = 0;
 - SpiMaster = SPI_MASTER_FROM_SPI_MASTER_PROTOCOL (This);
 - SpiRegBase = PcdGet32 (PcdSpiRegBase);
 - Length = 8 * DataByteCount;
 - EfiAcquireLock (&SpiMaster->Lock);
 - if (Flag & SPI_TRANSFER_BEGIN) {
 - SpiActivateCs (Slave->Cs);
 - }
 - // Set 8-bit mode
 - Reg = MmioRead32 (SpiRegBase + SPI_CONF_REG);
 - Reg &= ~SPI_BYTE_LENGTH;
 - MmioWrite32 (SpiRegBase + SPI_CONF_REG, Reg);
 - while (Length > 0) {
 - if (DataOut != NULL) {
 DataToSend = *DataOutPtr & 0xFF;- }
 - // Transmit Data
 - MmioWrite32 (SpiRegBase + SPI_DATA_OUT_REG, DataToSend);
 - // Wait for memory ready
 - for (Iterator = 0; Iterator < SPI_TIMEOUT; Iterator++) {
 if ((MmioRead32 (SpiRegBase + SPI_CTRL_REG) & SPI_MEM_READY_MASK) != 0) {*DataInPtr = MmioRead32 (SpiRegBase + SPI_DATA_IN_REG);if (DataInPtr != NULL) {DataInPtr++;}if (DataOutPtr != NULL) {DataOutPtr++;}Length -= 8;break;}- }
 - if (Iterator >= SPI_TIMEOUT) {
 DEBUG ((DEBUG_ERROR, "Timeout\n"));- }
 - }
 - if (Flag & SPI_TRANSFER_END) {
 - SpiDeactivateCs ();
 - }
 - EfiReleaseLock (&SpiMaster->Lock);
 - return EFI_SUCCESS;
 +}
+EFI_STATUS +EFIAPI +EfiSpiReadWrite (
- IN MARVELL_SPI_MASTER_PROTOCOL *This,
 - IN SPI_DEVICE *Slave,
 - IN UINT8 *Cmd,
 - IN UINTN CmdSize,
 - IN UINT8 *DataOut,
 - OUT UINT8 *DataIn,
 - IN UINTN DataSize
 - )
 +{
- EFI_STATUS Status;
 - Status = EfiSpiTransfer (This, Slave, CmdSize, Cmd, NULL, SPI_TRANSFER_BEGIN);
 - if (EFI_ERROR (Status)) {
 - Print (L"Spi Transfer Error\n");
 - return EFI_DEVICE_ERROR;
 - }
 - Status = EfiSpiTransfer (This, Slave, DataSize, DataOut, DataIn, SPI_TRANSFER_END);
 - if (EFI_ERROR (Status)) {
 - Print (L"Spi Transfer Error\n");
 - return EFI_DEVICE_ERROR;
 - }
 - return EFI_SUCCESS;
 +}
+EFI_STATUS +EFIAPI +EfiSpiInit (
- IN MARVELL_SPI_MASTER_PROTOCOL * This
 - )
 +{
- return EFI_SUCCESS;
 +}
+SPI_DEVICE * +EFIAPI +EfiSpiSetupSlave (
- IN MARVELL_SPI_MASTER_PROTOCOL *This,
 - IN UINTN Cs,
 - IN SPI_MODE Mode
 - )
 +{
- SPI_DEVICE *Slave;
 - Slave = AllocateZeroPool (sizeof(SPI_DEVICE));
 - if (Slave == NULL) {
 - DEBUG((DEBUG_ERROR, "Cannot allocate memory\n"));
 - return NULL;
 - }
 - Slave->Cs = Cs;
 - Slave->Mode = Mode;
 - SpiSetupTransfer (This, Slave);
 - return Slave;
 +}
+EFI_STATUS +EFIAPI +EfiSpiFreeSlave (
- IN SPI_DEVICE *Slave
 - )
 +{
- FreePool (Slave);
 - return EFI_SUCCESS;
 +}
+STATIC +EFI_STATUS +SpiMasterInitProtocol (
- IN MARVELL_SPI_MASTER_PROTOCOL *SpiMasterProtocol
 - )
 +{
- SpiMasterProtocol->Init = EfiSpiInit;
 - SpiMasterProtocol->SetupDevice = EfiSpiSetupSlave;
 - SpiMasterProtocol->FreeDevice = EfiSpiFreeSlave;
 - SpiMasterProtocol->Transfer = EfiSpiTransfer;
 - SpiMasterProtocol->ReadWrite = EfiSpiReadWrite;
 - return EFI_SUCCESS;
 +}
+EFI_STATUS +EFIAPI +SpiMasterEntryPoint (
- IN EFI_HANDLE ImageHandle,
 - IN EFI_SYSTEM_TABLE *SystemTable
 - )
 +{
- EFI_STATUS Status;
 - mSpiMasterInstance = AllocateZeroPool (sizeof (SPI_MASTER));
 - if (mSpiMasterInstance == NULL) {
 - return EFI_OUT_OF_RESOURCES;
 - }
 - EfiInitializeLock (&mSpiMasterInstance->Lock, TPL_NOTIFY);
 - SpiMasterInitProtocol (&mSpiMasterInstance->SpiMasterProtocol);
 - mSpiMasterInstance->Signature = SPI_MASTER_SIGNATURE;
 - Status = gBS->InstallMultipleProtocolInterfaces (
 &(mSpiMasterInstance->Handle),&gMarvellSpiMasterProtocolGuid,&(mSpiMasterInstance->SpiMasterProtocol),NULL);- if (EFI_ERROR (Status)) {
 - FreePool (mSpiMasterInstance);
 - return EFI_DEVICE_ERROR;
 - }
 - return EFI_SUCCESS;
 +} diff --git a/Drivers/Spi/MvSpiDxe.h b/Drivers/Spi/MvSpiDxe.h new file mode 100644 index 0000000..b85e9c1 --- /dev/null +++ b/Drivers/Spi/MvSpiDxe.h @@ -0,0 +1,145 @@ +/******************************************************************************* +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +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 Marvell 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 __SPI_MASTER_H__ +#define __SPI_MASTER_H__
+#include <Library/IoLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Uefi/UefiBaseType.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Spi.h>
+#define SPI_MASTER_SIGNATURE SIGNATURE_32 ('M', 'S', 'P', 'I') +#define SPI_MASTER_FROM_SPI_MASTER_PROTOCOL(a) CR (a, SPI_MASTER, SpiMasterProtocol, SPI_MASTER_SIGNATURE)
+// Marvell Flash Device Controller Registers +#define SPI_CTRL_REG (0x00) +#define SPI_CONF_REG (0x04) +#define SPI_DATA_OUT_REG (0x08) +#define SPI_DATA_IN_REG (0x0c) +#define SPI_INT_CAUSE_REG (0x10)
+// Serial Memory Interface Control Register Masks +#define SPI_CS_NUM_OFFSET 2 +#define SPI_CS_NUM_MASK (0x7 << SPI_CS_NUM_OFFSET) +#define SPI_MEM_READY_MASK (0x1 << 1) +#define SPI_CS_EN_MASK (0x1 << 0)
+// Serial Memory Interface Configuration Register Masks +#define SPI_BYTE_LENGTH_OFFSET 5 +#define SPI_BYTE_LENGTH (0x1 << SPI_BYTE_LENGTH_OFFSET) +#define SPI_CPOL_OFFSET 11 +#define SPI_CPOL_MASK (0x1 << SPI_CPOL_OFFSET) +#define SPI_CPHA_OFFSET 12 +#define SPI_CPHA_MASK (0x1 << SPI_CPHA_OFFSET) +#define SPI_TXLSBF_OFFSET 13 +#define SPI_TXLSBF_MASK (0x1 << SPI_TXLSBF_OFFSET) +#define SPI_RXLSBF_OFFSET 14 +#define SPI_RXLSBF_MASK (0x1 << SPI_RXLSBF_OFFSET)
+#define SPI_SPR_OFFSET 0 +#define SPI_SPR_MASK (0xf << SPI_SPR_OFFSET) +#define SPI_SPPR_0_OFFSET 4 +#define SPI_SPPR_0_MASK (0x1 << SPI_SPPR_0_OFFSET) +#define SPI_SPPR_HI_OFFSET 6 +#define SPI_SPPR_HI_MASK (0x3 << SPI_SPPR_HI_OFFSET)
+#define SPI_TRANSFER_BEGIN 0x01 // Assert CS before transfer +#define SPI_TRANSFER_END 0x02 // Deassert CS after transfers
+#define SPI_TIMEOUT 100000
+typedef struct {
- MARVELL_SPI_MASTER_PROTOCOL SpiMasterProtocol;
 - UINTN Signature;
 - EFI_HANDLE Handle;
 - EFI_LOCK Lock;
 +} SPI_MASTER;
+EFI_STATUS +EFIAPI +EfiSpiTransfer (
- IN MARVELL_SPI_MASTER_PROTOCOL *This,
 - IN SPI_DEVICE *Slave,
 - IN UINTN DataByteCount,
 - IN VOID *DataOut,
 - IN VOID *DataIn,
 - IN UINTN Flag
 - );
 +EFI_STATUS +EFIAPI +EfiSpiReadWrite (
- IN MARVELL_SPI_MASTER_PROTOCOL *This,
 - IN SPI_DEVICE *Slave,
 - IN UINT8 *Cmd,
 - IN UINTN CmdSize,
 - IN UINT8 *DataOut,
 - OUT UINT8 *DataIn,
 - IN UINTN DataSize
 - );
 +EFI_STATUS +EFIAPI +EfiSpiInit (
- IN MARVELL_SPI_MASTER_PROTOCOL * This
 - );
 +SPI_DEVICE * +EFIAPI +EfiSpiSetupSlave (
- IN MARVELL_SPI_MASTER_PROTOCOL * This,
 - IN UINTN Cs,
 - IN SPI_MODE Mode
 - );
 +EFI_STATUS +EFIAPI +EfiSpiFreeSlave (
- IN SPI_DEVICE *Slave
 - );
 +EFI_STATUS +EFIAPI +SpiMasterEntryPoint (
- IN EFI_HANDLE ImageHandle,
 - IN EFI_SYSTEM_TABLE *SystemTable
 - );
 +#endif // __SPI_MASTER_H__ diff --git a/Drivers/Spi/MvSpiDxe.inf b/Drivers/Spi/MvSpiDxe.inf new file mode 100644 index 0000000..1dd3029 --- /dev/null +++ b/Drivers/Spi/MvSpiDxe.inf @@ -0,0 +1,66 @@ +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute +# and/or modify this File under the following licensing terms. +# 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 Marvell 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. +#
+[Defines]
- INF_VERSION = 0x00010005
 - BASE_NAME = SpiMasterDxe
 - FILE_GUID = c19dbc8a-f4f9-43b0-aee5-802e3ed03d15
 - MODULE_TYPE = DXE_DRIVER
 - VERSION_STRING = 1.0
 - ENTRY_POINT = SpiMasterEntryPoint
 +[Sources]
- MvSpiDxe.c
 - MvSpiDxe.h
 +[Packages]
- MdePkg/MdePkg.dec
 - OpenPlatformPkg/Platforms/Marvell/Marvell.dec
 +[LibraryClasses]
- UefiBootServicesTableLib
 - UefiDriverEntryPoint
 - TimerLib
 - UefiLib
 - DebugLib
 - MemoryAllocationLib
 - IoLib
 +[FixedPcd]
- gMarvellTokenSpaceGuid.PcdSpiRegBase
 - gMarvellTokenSpaceGuid.PcdSpiClockFrequency
 - gMarvellTokenSpaceGuid.PcdSpiMaxFrequency
 +[Protocols]
- gMarvellSpiMasterProtocolGuid
 +[Depex]
- TRUE
 diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index 2604973..bb08334 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -113,6 +113,11 @@ gMarvellTokenSpaceGuid.PcdI2cClockFrequency|0|UINT32|0x3000048 gMarvellTokenSpaceGuid.PcdI2cBaudRate|0|UINT32|0x3000049 +#SPI
- gMarvellTokenSpaceGuid.PcdSpiRegBase|0|UINT32|0x3000051
 - gMarvellTokenSpaceGuid.PcdSpiMaxFrequency|0|UINT32|0x30000052
 - gMarvellTokenSpaceGuid.PcdSpiClockFrequency|0|UINT32|0x30000053
 [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} -- 1.8.3.1