Typically a command for the UFS host controller consists of a UTP Transfer Request List entry and a command table element. Thus, the host software needs to start by finding an empty slot inside the UTP Transfer Request List first.
Here are the basic steps for setting up the command list:
- Find an empty command list slot by reading the
UFS_UTRLDBR register.
- In case there are no empty slots, wait and try again.
- In case there is at least one empty slot, start setting up the UTP Transfer Request Descriptor:
- Write CT: define command type.
- Write DD: define data direction.
- Write I: define whether or not an interrupt has to be generated.
- Initialize OCS with the value Fh.
- Allocate space inside the system memory for an UTP Command Descriptor.
- Initialize Command UPIU field of the UTP Command Descriptor:
- Write TTY: transaction type, here 1h.
- Write FL: specific flags for this command.
- Write LUN: the SCSI address this command is directed to.
- Write TT: task tag, a unique number to identify the task.
- Write CST: command set type, 0h for SCSI commands.
- Write TEL: total EHS Length, always 0h.
- Write DSL: data segment length, always 0h.
- Write EDTL: expected data transfer length. This field indicates the amount of data to be transferred between the Initiator and Target (read or write). Data is stored in system memory.
- Write CDB: write the SCSI command into the following 16 bytes.
- Initialize Response UPIU field of the UTP Command Descriptor with zero.
- Initialize PRD field of the UTP Command Descriptor with the required data scatter/gather buffer information.
- Now the UTP Command Descriptor has been set up and the UTP Transfer Request List Descriptor needs to be completed:
- Write UCDBA: base address of the UTP Command Descriptor.
- Write UCDBAU: upper 32 bit of the UCDBA, always 0h.
- Program field RUO with the offset (from the starting address of UCD) of Response UPIU within UCD.
- Program field RUL with the length of Response UPIU.
- Program field PRDTO with the offset (from the starting address of UCD) of the PRD table within UCD if required.
- Program field PRDTL with the length of the PRD table if required.
- Repeat this procedure for all commands which need to be set up.
- Check the UFS_UTRLRSR register and make sure it
is read 1h before continuing.
- Set UTP Transfer Request Interrupt Aggregation
Control Register (UFS_UTRIACR) enable bit to 1h to enable the
interrupt.
- Set Counter and Timer Reset (UFS_UTRIACR[16] CTR)
bit to 1h to reset the counter and timer associated with the interrupt.
- Program field Interrupt aggregation counter
threshold (UFS_UTRIACR[12-8] IACTH) with the number of command completions
that are required to generate an interrupt.
- Program field Interrupt aggregation timeout value
(UFS_UTRIACR[7-0] IATOVAL) with the maximum time allowed between a response
arrival to the UFS host controller and the generation of an interrupt.
- Set the UFS_UTRLDBR register to ring the doorbell
register to indicate to the UFS host controller that one or more transfer
requests are ready to be sent to the attached device. The host software
shall only write a 1h to the bit position that corresponding to the new
command. All other bit positions within the UFS_UTRLDBR register should be
written with a 0h, which indicates no change to their current values.
Now the UFS host controller will take over and process the command list without further software interaction.