Skip to main content

QUP v3 overview

The QUP v3 is a highly flexible and programmable hardware for supporting a wide range of serial interface. A single QUP v3 serial engine hardware core provides up to eight serial interfaces. The two QUP v3 hardware cores are as follows:
  • 16-serial engine core
  • SSC QUP v3 hardware core with five serial engines available in the SSC_I/Os
The QUP v3 supports access from multiple hardware entities in the system. Each entity has its own execution environment (EE), a separate address space, and an interrupt line. For information about the various transfer modes that can be configured in QUP v3, see Supported transfer modes in QUP v3. The following figure shows one GSI core/engine connected with up to eight serial engines (SE). You have the flexibility to customize configurations depending on the use case or the protocol of the serial engine. For information about how to customize configurations, see QUP v3 access control customization. To verify if the QUP v3 firmware is correctly flashed, see QUP v3 firmware status verification.
QUPv3 block diagram

Figure : QUP v3 block diagram

Supported transfer modes in QUP v3

The following modes can be configured in the QUP v3 serial engine.
  • FIFO mode: Simple and reliable, but CPU-intensive. Best suited for low-traffic control operations and basic bring-up.
  • CPU DMA (SE DMA mode): Offloads data movement but still relies on CPU coordination. Delivers moderate performance improvements.
  • Generic software interface (GSI) DMA mode (preferred): Fully hardware-driven transfers with minimal CPU involvement. Optimized for high performance, scalability, and power efficiency.
Table : User-level comparison summary
AspectFIFOCPU DMAGSI DMA
CPU involvementHighMediumMinimal
Interrupt frequencyHighMediumVery low
Power efficiencyLowMediumHigh
Performance scalabilityPoorModerateExcellent
Best forSimple controlMedium transfersHigh-performance systems
QUPv3 GENI supports multiple data movement mechanisms. Traditionally, transfers could be performed using FIFO (PIO-based) or CPU-managed DMA modes. While these approaches are sufficient for low-throughput or infrequent transfers, they place a continuous load on the CPU and generate a high interrupt rate under heavy traffic conditions.

QUPv3 GENI transfer modes

QUPv3 GENI supports multiple data movement mechanisms. Traditionally, transfers could be performed using FIFO (PIO-based) or CPU-managed DMA modes. While these approaches are sufficient for low-throughput or infrequent transfers, they place a continuous load on the CPU and generate a high interrupt rate under heavy traffic conditions. FIFO mode
Fifo mode

Figure : FIFO mode

  1. ①: The application processor configures the generic interface (GENI).
  2. ②: The application processor processes Rx/Tx data. The data is transferred between GENI and memory.
DMA mode
DMA mode

Figure : DMA mode

  1. ①: The application processor initializes DMA.
  2. ②: The serial engine configures GENI, and initiates the transfer process.
GSI mode GSI mode introduces a hardware-assisted, descriptor-based DMA mechanism using Qualcomm’s GPI DMA engine. In this mode, the CPU programs a set of transaction descriptors—called Transaction Ring Elements (TREs)—that fully describe an I/O operation. Once submitted, the GPI hardware autonomously executes the transfer, moving data between system memory and the GENI Serial Engine without further CPU intervention. GSI mode is best suited for the following use cases:
  • High-speed I3C devices
  • Camera and Ethernet subsystems
  • PCIe switches over I2C
The system-level benefits of using GSI mode are as follows:
  • Major CPU offload
  • Fewer interrupts
  • Better scalability under load
  • Performance improvements
    • Stable performance for large transfers
    • Lower interrupt rate per transfer
    • Predictable latency
    • Consistent throughput at high speeds
    • No sharp degradation for large payloads
GSI mode

Figure : GSI mode

  1. ①: The application processor prepares TRE.
  2. ②: The application processor informs QUP (GSI).
  3. ③: The GSI processes TRE.
  4. ④: After the TRE completes processing, it’s sent to GENI.
  5. ⑤: The serial engine processes the Rx/Tx data.
NoteThe QUP v3 UART serial engine doesn’t support the GSI mode.

QUP v3 access control customization

The QUP v3 user access file QUPAC_Access.c specifies the owners of the serial engine resource. Initially, it’s populated according to the system I/O GPIO allocation. All serial engines must be listed to access the subsystem. It’s flexible enough to list only the available serial engine on a particular device. To customize the access control for the required serial engine protocol, configure the parameters in the QUPAC_Access.c file. The Qualcomm TEE image for the QUPAC_Access.c file is at /firmware/qualcomm-linux-spf-1-0_ap_standard_oem_nomodem/TZ.XF.5.0/trustzone_images/core/settings/buses/qup_accesscontrol/qupv3/config/<chipset>/QUPAC_Access.c. To specify the owner of the serial engine resource, modify the QUPAC_Access.c file to suit the board design. The following use case specifies the default protocol that operates on an enabled serial engine. You can modify the code according to your board design. Nonsecure mode use case in QUP v3 serial engine The following nonsecure mode use cases are supported in the QUP v3 serial engine.
const QUPv3_se_security_permissions_type qupv3_perms_iot_rb3[] =
{
    /*  PeriphID,      ProtocolID,              Mode,      NsOwner,
        bAllowFifo,   bLoad,   bModExcl */
    { QUPV3_0_SE0, QUPV3_PROTOCOL_I2C,     QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // LT9611 and QPS615 I2C
    { QUPV3_0_SE1, QUPV3_PROTOCOL_I2C,     QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // APPS I2C - PCIE/ USB Type C
    { QUPV3_0_SE2, QUPV3_PROTOCOL_I2C,     QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // SMB / LS1 I2C
    { QUPV3_0_SE3, QUPV3_PROTOCOL_SPI,     QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // CAN SPI
    { QUPV3_0_SE4, QUPV3_PROTOCOL_UART_4W, QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // LS1 UART
    { QUPV3_0_SE5, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, FALSE, FALSE }, // Debug UART
    { QUPV3_0_SE6, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // WLAN UART
    { QUPV3_0_SE7, QUPV3_PROTOCOL_UART_4W, QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // Hastings BT
    { QUPV3_1_SE0, QUPV3_PROTOCOL_SPMI,    QUPV3_MODE_FIFO, AC_ADSP_Q6_ELF,
      TRUE, TRUE, FALSE }, // QuP SPMI
    { QUPV3_1_SE1, QUPV3_PROTOCOL_I2C,     QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // NFC I2C
    { QUPV3_1_SE2, QUPV3_PROTOCOL_I2C,     QUPV3_MODE_FIFO, AC_HLOS,
      TRUE, TRUE, FALSE }, // HDMI OUT for VIDEOIOBoard
    { QUPV3_1_SE3, QUPV3_PROTOCOL_SPI,     QUPV3_MODE_FIFO, AC_HLOS,
      FALSE, TRUE, FALSE }, // LS1 SPI
    { QUPV3_1_SE4, QUPV3_PROTOCOL_SPI,     QUPV3_MODE_GSI,  AC_TZ,
      FALSE, TRUE, FALSE }, // SPI -NFC ESE
    { QUPV3_1_SE5, QUPV3_PROTOCOL_I2C,     QUPV3_MODE_GSI,  AC_HLOS,
      FALSE, TRUE, FALSE}, // Legacy Touch
    { QUPV3_1_SE6, QUPV3_PROTOCOL_SPI,     QUPV3_MODE_GSI,  AC_HLOS,
      FALSE, TRUE, FALSE}, // FP
    /*QUPV3_1_SE7*/
};

QUP v3 serial engine access list description

The following variables are passed into the QUPv3_se_security_permissions_type structure. Table : Security permission variables for QUP v3
VariablesDescription
PeriphIDSerial engine peripheral to configure and assign.
ProtocolIDMacro of the required protocol.
ModeMacro of FIFO/GSI/DMA modes.
NsOwnerHolds a macro of the image that needs access.
bAllowFifoThe boolean flag is set to True if the mode is FIFO, else the flag is set to False.
bLoadThe boolean flag value is set to True to load the protocol firmware.
bModExclThis flag is exclusively for Qualcomm TEE. It’s set to True when NsOwner is AC_TZ.
For more information about this macro, see settings/buses/qup_accesscontrol/qupv3/interface/QupACCommonIds.h.

QUP v3 firmware status verification

For serial engines to work, the QUP firmware must be flashed correctly. The firmware is delivered through the metabuild at common/core_qupv3fw/<chipset>/qupv3fw.elf. You can verify the firmware status by checking GENI_FW_REVISION_RO (0xa8c068). For example, identify the register in the kernel log for the 0x0000ffff value. In the following log, the 0000ffff error indicates that the firmware isn’t flashed correctly.
0a8c068: 0000ffff //Invalid firmware or firmware not loaded
00a80069: 00000126 //SPI
00a80068: 00000338 //I2C
Modify the QUPAC_Access.c file configuration only if you intend to use a protocol different from the default configuration. The following sample log is displayed when configurations don’t match after loading.
msm_geni_serial 898000.qcom,qup_uart:msm_geni_serial_startup: Invalid FW 255 loaded
TitleResource
Qualcomm Technologies, Inc.
Secure shellhttps://docs.qualcomm.com/bundle/publicresource/topics/80-80022-254/how_to.html
QDTEhttps://docs.qualcomm.com/bundle/publicresource/topics/80-80022-4/tools.html#qdte
Resources
PCI bus subsystemhttps://www.kernel.org/doc/html/latest/PCI/index.html
Linux user space exampleshttps://github.com/DigilientLinux-userspace-examples/tree/master/uart_example_linux/src
DTSI configuration exampleshttps://github.com/torvalds/linux/blob/master/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
Test tools and methods for the UART serial interface driverhttps://docs.kernel.org/admin-guide/serial-console.html
UART Linux APIshttps://github.com/torvalds/linux/blob/master/include/linux/tty.h
UART upstream device tree referencehttps://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi
Qualcomm Dragonwing RB3 Gen 2 Development Kit device tree nodehttps://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
SPI kernel toolshttps://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/spi
SPI upstream device tree referencehttps://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi
I2C samples
I2C Linux APIs
I2C upstream kernel test applications and I2C toolhttps://layers.openembedded.org/layerindex/recipe/27859/
I2C upstream device tree referencehttps://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi
PCIe device initialization and enumeration processhttps://www.kernel.org/doc/html/latest/PCI/index.html
PCIe framework and client driver PCIe registrationshttps://www.kernel.org/doc/html/latest/PCI/index.html
Add MSI groups supported for a PCIe instancehttps://lore.kernel.org/linux-arm-msm/f1168212-bc6e-4570-869c-2870d6f248ad@linaro.org/T/
PCIe debugginghttps://pcisig.com/specifications
PCIe upstream device tree reference
USB Qscratch wrapper driverhttps://github.com/torvalds/linux/blob/master/drivers/usb/dwc3/dwc3-qcom.c
Controller core driverhttps://github.com/torvalds/linux/blob/master/drivers/usb/dwc3/core.c
USB software interface drivers for Type-C connector
LPM supporthttps://lore.kernel.org/20231017131851.8299-1-quic_kriskura@quicinc.com/
USB DWC3 driverhttps://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/usb/dwc3/dwc3-qcom.c?h=v6.6.2
Qualcomm Synopsys femto PHYhttps://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c?h=v6.6.2
QMP DisplayPort combo PHYhttps://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/phy/qualcomm/phy-qcom-qmp-combo.c?h=v6.6.2
USB ADBhttps://developer.android.com/tools/adb
f_fs.chttps://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/usb/gadget/function/f_fs.c?h=v6.6.2
Mass storagehttps://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/usb/gadget/function/f_mass_storage.c?h=v6.6.2
Platform tools (adb/fastboot)https://developer.android.com/tools/releases/platform-tools
Platform LibUVC
UVC gadgethttps://github.com/wlhe/uvc-gadget
UVC streamerhttps://github.com/bsapundzhiev/uvc-streamer
UVC Video4Linux (v4l2-utils)https://linuxtv.org/downloads/v4l-dvb-apis/driver-api/v4l2-core.html
USB upstream device tree referencehttps://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/sc7280.dtsi
Qualcomm Linux hardware SoC device-tree nodehttps://git.linaro.org/kernel-org/linux-next.git/tree/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
RPM changes in the USB driver and other exampleshttps://patchwork.kernel.org/project/linux-usb/list/?series=793939&archive=both
Flatten a device tree

Acronyms and terms

Acronym or termDefinition
aDSPApplication digital signal processor
ADBAndroid debug bridge
ASPMActive state power management
BDFBus device function
CANController area network
CRCCyclic redundancy check
CTSClear to send
DLLPData link layer packet
DTSDevice tree source
ECRCEnd-to-end CRC
EEExecution environment
ESEExecute secure environment
FPFingerprint
GPIOGeneral-purpose input/output
GSIGeneric software interface
HIDHuman interface device
I/OInput/output
IOMMUInput/output memory management unit
I2CInterintegrated circuit
I3CImproved interintegrated circuit
LSPList processor
MSMass storage
MSIMessage signaled interrupt
NCMNetwork control modem
NFCNear-field communication
NICNetwork interface card
PCIePeripheral component interconnect express
QoSQuality of service
QIMQualcomm intelligent multimedia
RTSRequest to send
SCLSerial clock line
SDKSoftware development kit
SDLSerial data line
SESerial engine
SLPISensor low-power island
SPISerial peripheral interface
SPMISystem power management interface
SR-IOVSingle root I/O virtualization
SSCSnapdragon sensor core
TCTraffic class
TEETrusted execution environment
TLPTransaction layer packet
UEFIUnified extensible firmware interface
UACUSB audio class
UARTUniversal asynchronous receiver-transmitter
UCSIUSB Type-C connector system software interface
V4L2Video4Linux2
VCVirtual channel
YavtaYet another V4L2 test application