From: Leif Lindholm <leif.lindholm@linaro.org>
To: Pankaj Bansal <pankaj.bansal@nxp.com>
Cc: edk2-devel@lists.01.org, V.Sethi@nxp.com, udit.kumar@nxp.com,
Michael D Kinney <michael.d.kinney@intel.com>,
Liming Gao <liming.gao@intel.com>
Subject: Re: [RFC] MdePkg/Spi : Modify SPI Protocol strctures to make it more generic
Date: Thu, 7 Dec 2017 14:48:51 +0000 [thread overview]
Message-ID: <20171207144851.ld2vbgo6az2shquy@bivouac.eciton.net> (raw)
In-Reply-To: <1512635719-32003-1-git-send-email-pankaj.bansal@nxp.com>
Adding MdePkg maintainers: Mike and Liming.
Please always cc package maintainers (listed in Maintainers.txt).
/
Leif
On Thu, Dec 07, 2017 at 02:05:19PM +0530, Pankaj Bansal wrote:
> Issue_1: Currenty SPI IO and SPI HC protocol strcture is not equipped
> to handle all type of SPI commands
> e.g. QuadIo Read Command (0xEBh) in spansion flash S25FS512S will not
> work.
>
> Cause: Currenty SPI protocol describes a SPI transaction as combination
> of data and address and command, which would all be transmitted on
> same data bus (1 or 2 or 4).
>
> BUT when we have a case in which command is send one single data bus and
> address and data is sent one 4 data bus (like 0xEB in spansion), then
> this will not work with current strcture.
>
> Fix: Instead of making a single transaction, we can specify a group of
> transactions (called packet, terminology borrowed from I2c Protocol) in
> which each transaction specifies the data width, frequency, delay and
> read/write info.
>
> Issue_2: Specify additional data about SPI transaction (i.e. transaction
> is of type cmd, address, data, dummy etc). some controllers need this
> info to communicate with SPI peripheral. others can ignore this info.
>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
> ---
> MdePkg/Include/Protocol/SpiHc.h | 15 +-
> MdePkg/Include/Protocol/SpiIo.h | 250 ++++++++++++------------------
> 2 files changed, 104 insertions(+), 161 deletions(-)
>
> diff --git a/MdePkg/Include/Protocol/SpiHc.h b/MdePkg/Include/Protocol/SpiHc.h
> index 12fe5d2..65964bc 100644
> --- a/MdePkg/Include/Protocol/SpiHc.h
> +++ b/MdePkg/Include/Protocol/SpiHc.h
> @@ -110,8 +110,11 @@ typedef EFI_STATUS
> status.
>
> @param[in] This Pointer to an EFI_SPI_HC_PROTOCOL structure.
> - @param[in] BusTransaction Pointer to a EFI_SPI_BUS_ TRANSACTION containing
> - the description of the SPI transaction to perform.
> + @param[in] SpiPeripheral The address of an EFI_SPI_PERIPHERAL data structure
> + describing the SPI peripheral from(to) which
> + read(write) transactions to be performed.
> + @param[in] RequestPacket Pointer to a EFI_SPI_REQUEST_PACKET containing
> + the description of the SPI transactions to perform.
>
> @retval EFI_SUCCESS The transaction completed successfully
> @retval EFI_BAD_BUFFER_SIZE The BusTransaction->WriteBytes value is invalid,
> @@ -124,7 +127,8 @@ typedef EFI_STATUS
> typedef EFI_STATUS
> (EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> IN CONST EFI_SPI_HC_PROTOCOL *This,
> - IN EFI_SPI_BUS_TRANSACTION *BusTransaction
> + IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> + IN EFI_SPI_REQUEST_PACKET *RequestPacket
> );
>
> ///
> @@ -135,7 +139,6 @@ struct _EFI_SPI_HC_PROTOCOL {
> /// Host control attributes, may have zero or more of the following set:
> /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> - /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> /// - The SPI host controller requires the transmit frame to be in most
> /// significant bits instead of least significant bits.The host driver
> @@ -149,10 +152,6 @@ struct _EFI_SPI_HC_PROTOCOL {
> /// - The SPI controller supports a 2 - bit data bus
> /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> /// - The SPI controller supports a 4 - bit data bus
> - /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> - /// - Transfer size includes the opcode byte
> - /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> - /// - Transfer size includes the 3 address bytes
> /// The SPI host controller must support full - duplex (receive while
> /// sending) operation.The SPI host controller must support a 1 - bit bus
> /// width.
> diff --git a/MdePkg/Include/Protocol/SpiIo.h b/MdePkg/Include/Protocol/SpiIo.h
> index 43e8045..507abb5 100644
> --- a/MdePkg/Include/Protocol/SpiIo.h
> +++ b/MdePkg/Include/Protocol/SpiIo.h
> @@ -27,147 +27,33 @@ typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> /// Note: The UEFI PI 1.6 specification does not specify values for the
> /// members below. The order matches the specification.
> ///
> +///
> +/// SPI peripheral transfer type
> +///
> +/// The EFI_SPI_TRANSACTION_TYPE describes the type of SPI transaction to either
> +/// send or recievce from SPI peripheral.
> +/// some SPI controllers need this information to complete a SPI operation
> +/// (which consists of one or many transactions)
> +///
> +/// for other controllers this field may be left 0 (SPI_TRANSACTION_NONE)
> +///
> typedef enum {
> - ///
> - /// Data flowing in both direction between the host and
> - /// SPI peripheral.ReadBytes must equal WriteBytes and both ReadBuffer and
> - /// WriteBuffer must be provided.
> - ///
> - SPI_TRANSACTION_FULL_DUPLEX,
> -
> - ///
> - /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> - /// zero.WriteBytes must be non - zero and WriteBuffer must be provided.
> - ///
> - SPI_TRANSACTION_WRITE_ONLY,
> -
> - ///
> - /// Data flowing from the SPI peripheral to the host.WriteBytes must be
> - /// zero.ReadBytes must be non - zero and ReadBuffer must be provided.
> - ///
> - SPI_TRANSACTION_READ_ONLY,
> -
> - ///
> - /// Data first flowing from the host to the SPI peripheral and then data
> - /// flows from the SPI peripheral to the host.These types of operations get
> - /// used for SPI flash devices when control data (opcode, address) must be
> - /// passed to the SPI peripheral to specify the data to be read.
> - ///
> - SPI_TRANSACTION_WRITE_THEN_READ
> -} EFI_SPI_TRANSACTION_TYPE;
> -
> -/**
> - Initiate a SPI transaction between the host and a SPI peripheral.
> -
> - This routine must be called at or below TPL_NOTIFY.
> - This routine works with the SPI bus layer to pass the SPI transaction to the
> - SPI controller for execution on the SPI bus. There are four types of
> - supported transactions supported by this routine:
> - * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> - * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes = 0
> - * Read Only: ReadBuffer to receive data from SPI peripheral, WriteBytes = 0
> - * Write Then Read: WriteBuffer contains control data to write to SPI
> - peripheral before data is placed into the ReadBuffer.
> - Both WriteBytes and ReadBytes must be non-zero.
> -
> - @param[in] This Pointer to an EFI_SPI_IO_PROTOCOL structure.
> - @param[in] TransactionType Type of SPI transaction.
> - @param[in] DebugTransaction Set TRUE only when debugging is desired.
> - Debugging may be turned on for a single SPI
> - transaction. Only this transaction will display
> - debugging messages. All other transactions with
> - this value set to FALSE will not display any
> - debugging messages.
> - @param[in] ClockHz Specify the ClockHz value as zero (0) to use
> - the maximum clock frequency supported by the
> - SPI controller and part. Specify a non-zero
> - value only when a specific SPI transaction
> - requires a reduced clock rate.
> - @param[in] BusWidth Width of the SPI bus in bits: 1, 2, 4
> - @param[in] FrameSize Frame size in bits, range: 1 - 32
> - @param[in] WriteBytes The length of the WriteBuffer in bytes.
> - Specify zero for read-only operations.
> - @param[in] WriteBuffer The buffer containing data to be sent from the
> - host to the SPI chip. Specify NULL for read
> - only operations.
> - * Frame sizes 1-8 bits: UINT8 (one byte) per
> - frame
> - * Frame sizes 7-16 bits: UINT16 (two bytes) per
> - frame
> - * Frame sizes 17-32 bits: UINT32 (four bytes)
> - per frame The transmit frame is in the least
> - significant N bits.
> - @param[in] ReadBytes The length of the ReadBuffer in bytes.
> - Specify zero for write-only operations.
> - @param[out] ReadBuffer The buffer to receeive data from the SPI chip
> - during the transaction. Specify NULL for write
> - only operations.
> - * Frame sizes 1-8 bits: UINT8 (one byte) per
> - frame
> - * Frame sizes 7-16 bits: UINT16 (two bytes) per
> - frame
> - * Frame sizes 17-32 bits: UINT32 (four bytes)
> - per frame The received frame is in the least
> - significant N bits.
> -
> - @retval EFI_SUCCESS The SPI transaction completed successfully
> - @retval EFI_BAD_BUFFER_SIZE The writeBytes value was invalid
> - @retval EFI_BAD_BUFFER_SIZE The ReadBytes value was invalid
> - @retval EFI_INVALID_PARAMETER TransactionType is not valid,
> - or BusWidth not supported by SPI peripheral or
> - SPI host controller,
> - or WriteBytes non-zero and WriteBuffer is
> - NULL,
> - or ReadBytes non-zero and ReadBuffer is NULL,
> - or ReadBuffer != WriteBuffer for full-duplex
> - type,
> - or WriteBuffer was NULL,
> - or TPL is too high
> - @retval EFI_OUT_OF_RESOURCES Insufficient memory for SPI transaction
> - @retval EFI_UNSUPPORTED The FrameSize is not supported by the SPI bus
> - layer or the SPI host controller
> - @retval EFI_UNSUPPORTED The SPI controller was not able to support
> -
> -**/
> -typedef
> -EFI_STATUS
> -(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> - IN CONST EFI_SPI_IO_PROTOCOL *This,
> - IN EFI_SPI_TRANSACTION_TYPE TransactionType,
> - IN BOOLEAN DebugTransaction,
> - IN UINT32 ClockHz OPTIONAL,
> - IN UINT32 BusWidth,
> - IN UINT32 FrameSize,
> - IN UINT32 WriteBytes,
> - IN UINT8 *WriteBuffer,
> - IN UINT32 ReadBytes,
> - OUT UINT8 *ReadBuffer
> - );
> + SPI_TRANSACTION_NONE = 0,
>
> -/**
> - Update the SPI peripheral associated with this SPI 10 instance.
> + /// Command to send to SPI peripheral
> + SPI_TRANSACTION_COMMAND,
>
> - Support socketed SPI parts by allowing the SPI peripheral driver to replace
> - the SPI peripheral after the connection is made. An example use is socketed
> - SPI NOR flash parts, where the size and parameters change depending upon
> - device is in the socket.
> + /// Address from/to which data is to be read/written
> + SPI_TRANSACTION_ADDRESS,
>
> - @param[in] This Pointer to an EFI_SPI_IO_PROTOCOL structure.
> - @param[in] SpiPeripheral Pointer to an EFI_SPI_PERIPHERAL structure.
> + /// Dummy cycles
> + /// Some SPI peripherals need dummy clock cycles which can be used by
> + /// peripherals to have some delay between transfers.
> + SPI_TRANSACTION_DUMMY,
>
> - @retval EFI_SUCCESS The SPI peripheral was updated successfully
> - @retval EFI_INVALID_PARAMETER The SpiPeripheral value is NULL,
> - or the SpiPeripheral->SpiBus is NULL,
> - or the SpiP eripheral - >SpiBus pointing at
> - wrong bus,
> - or the SpiP eripheral - >SpiPart is NULL
> -
> -**/
> -typedef EFI_STATUS
> -(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> - IN CONST EFI_SPI_IO_PROTOCOL *This,
> - IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral
> - );
> + /// Data Request (Read/write)
> + SPI_TRANSACTION_DATA,
> +} EFI_SPI_TRANSACTION_TYPE;
>
> ///
> /// The EFI_SPI_BUS_ TRANSACTION data structure contains the description of the
> @@ -175,11 +61,6 @@ typedef EFI_STATUS
> ///
> typedef struct _EFI_SPI_BUS_TRANSACTION {
> ///
> - /// Pointer to the SPI peripheral being manipulated.
> - ///
> - CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> -
> - ///
> /// Type of transaction specified by one of the EFI_SPI_TRANSACTION_TYPE
> /// values.
> ///
> @@ -204,9 +85,9 @@ typedef struct _EFI_SPI_BUS_TRANSACTION {
> UINT32 FrameSize;
>
> ///
> - /// Length of the write buffer in bytes
> + /// Length of the buffer (read or write or both) in bytes
> ///
> - UINT32 WriteBytes;
> + UINT32 Bytes;
>
> ///
> /// Buffer containing data to send to the SPI peripheral
> @@ -216,20 +97,87 @@ typedef struct _EFI_SPI_BUS_TRANSACTION {
> UINT8 *WriteBuffer;
>
> ///
> - /// Length of the read buffer in bytes
> - ///
> - UINT32 ReadBytes;
> -
> - ///
> /// Buffer to receive the data from the SPI peripheral
> /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> ///
> UINT8 *ReadBuffer;
> +
> + /// delay afer transaction
> + UINT32 DelayMicroSeconds;
> +
> + /// Specify the ClockHz value as zero (0) to use
> + /// the maximum clock frequency supported by the
> + /// SPI controller and part. Specify a non-zero
> + /// value only when a specific SPI transaction
> + /// requires a reduced clock rate.
> + UINT32 ClockHz;
> } EFI_SPI_BUS_TRANSACTION;
>
> ///
> +/// SPI device request
> +///
> +/// The EFI_SPI_REQUEST_PACKET describes single SPI operation,
> +/// between Chip Select deassert and Chip Select assert.
> +/// Some operation will consist of a single transaction while others will
> +/// be two or more.
> +///
> +typedef struct _EFI_SPI_REQUEST_PACKET {
> + ///
> + /// Number of elements in the operation array
> + ///
> + UINTN TransactionCount;
> + ///
> + /// Description of the SPI operation
> + ///
> + EFI_SPI_BUS_TRANSACTION Transaction [1];
> +} EFI_SPI_REQUEST_PACKET;
> +
> +/**
> + Initiate a SPI transaction between the host and a SPI peripheral.
> +
> + This routine must be called at or below TPL_NOTIFY.
> + This routine works with the SPI bus layer to pass the SPI transaction to the
> + SPI controller for execution on the SPI bus.
> +
> + @param[in] This Pointer to an EFI_SPI_IO_PROTOCOL structure.
> + @param[in] RequestPacket Pointer to an EFI_SPI_REQUEST_PACKET structure
> + describing the SPI transaction
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> + IN CONST EFI_SPI_IO_PROTOCOL *This,
> + IN EFI_SPI_REQUEST_PACKET *RequestPacket,
> + );
> +
> +/**
> + Update the SPI peripheral associated with this SPI 10 instance.
> +
> + Support socketed SPI parts by allowing the SPI peripheral driver to replace
> + the SPI peripheral after the connection is made. An example use is socketed
> + SPI NOR flash parts, where the size and parameters change depending upon
> + device is in the socket.
> +
> + @param[in] This Pointer to an EFI_SPI_IO_PROTOCOL structure.
> + @param[in] SpiPeripheral Pointer to an EFI_SPI_PERIPHERAL structure.
> +
> + @retval EFI_SUCCESS The SPI peripheral was updated successfully
> + @retval EFI_INVALID_PARAMETER The SpiPeripheral value is NULL,
> + or the SpiPeripheral->SpiBus is NULL,
> + or the SpiP eripheral - >SpiBus pointing at
> + wrong bus,
> + or the SpiP eripheral - >SpiPart is NULL
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> + IN CONST EFI_SPI_IO_PROTOCOL *This,
> + IN CONST EFI_SPI_PERIPHERAL *SpiPeripheral
> + );
> +
> +///
> /// Support managed SPI data transactions between the SPI controller and a SPI
> /// chip.
> ///
> @@ -262,14 +210,10 @@ struct _EFI_SPI_IO_PROTOCOL {
>
> ///
> /// Transaction attributes: One or more from:
> - /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> + /// * SPI_IO_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> /// - The SPI host and peripheral supports a 2-bit data bus
> /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> /// - The SPI host and peripheral supports a 4-bit data bus
> - /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> - /// - Transfer size includes the opcode byte
> - /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> - /// - Transfer size includes the 3 address bytes
> ///
> UINT32 Attributes;
>
> --
> 2.7.4
>
next prev parent reply other threads:[~2017-12-07 14:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-07 8:35 [RFC] MdePkg/Spi : Modify SPI Protocol strctures to make it more generic Pankaj Bansal
2017-12-07 14:48 ` Leif Lindholm [this message]
2017-12-08 5:22 ` Bi, Dandan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171207144851.ld2vbgo6az2shquy@bivouac.eciton.net \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox