> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# UART

UART (Universal Asynchronous Receiver-Transmitter) transmits data asynchronously using start and stop bits instead of a clock signal. The receiving UART reads bits at a specific frequency known as the baud rate.

<img src="https://mintcdn.com/qualcomm-prod/jy6NQT2Y7J_sAxdX/Linux/images/peripheral-interfaces/uart_connection_diagram.png?fit=max&auto=format&n=jy6NQT2Y7J_sAxdX&q=85&s=6b6f9aae1a381ae368928049f015f74e" width="642" height="253" data-path="Linux/images/peripheral-interfaces/uart_connection_diagram.png" />

## Key Parameters

* **Baud rate** — Communication speed (bits per second)
* **Start/Stop bits** — Frame delimiters
* **Parity bit** — Optional error checking
* **Data bits** — 5–9 bits per frame
* **Flow control** — Hardware handshaking via CTS/RTS

<img src="https://mintcdn.com/qualcomm-prod/jy6NQT2Y7J_sAxdX/Linux/images/peripheral-interfaces/uart_data_frame.png?fit=max&auto=format&n=jy6NQT2Y7J_sAxdX&q=85&s=88b18550eeb400ddd30f8bfc9efc6c14" width="995" height="153" data-path="Linux/images/peripheral-interfaces/uart_data_frame.png" />

## Transfer Modes by Subsystem

| Subsystem       | Transfer Mode | Baud Rates                                 | Notes                           |
| --------------- | ------------- | ------------------------------------------ | ------------------------------- |
| **Linux**       | FIFO, CPU DMA | 300 bps – 4 Mbps                           | DMA ideal for Bluetooth modules |
| **Boot (UEFI)** | FIFO only     | Up to 115200                               | 5–8 bits per character          |
| **aDSP**        | FIFO only     | 115200, 230400, 460800, 921600, 1M, 3M, 6M | 5–8 bits per character          |

## Interface Components

### Device Tree Sources

| Platform           | File                                   |
| ------------------ | -------------------------------------- |
| Dragonwing IQ-9075 | `arch/arm64/boot/dts/qcom/lemans.dtsi` |

### APIs

| Subsystem | Header                            |
| --------- | --------------------------------- |
| Linux     | `include/linux/tty.h`             |
| Boot      | `QcomPkg/Include/HSUart.h`        |
| aDSP      | `adsp_proc/core/api/buses/uart.h` |

## Software Configuration

### Linux Device Tree Example

**4-wire UART (with flow control):**

```dts theme={null}
uart7: serial@99c000 {
    compatible = "qcom,geni-uart";
    reg = <0 0x0099c000 0 0x4000>;
    clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
    clock-names = "se";
    pinctrl-names = "default";
    pinctrl-0 = <&qup_uart7_cts>, <&qup_uart7_rts>,
                <&qup_uart7_tx>, <&qup_uart7_rx>;
    interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
    power-domains = <&rpmhpd SC7280_CX>;
    interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
                    <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_QUP_0 0>;
    interconnect-names = "qup-core", "qup-config";
    status = "disabled";
};
```

GPIO pinctrl:

```dts theme={null}
qup_uart7_cts: qup-uart7-cts-state { pins = "gpio28"; function = "qup07"; };
qup_uart7_rts: qup-uart7-rts-state { pins = "gpio29"; function = "qup07"; };
qup_uart7_tx:  qup-uart7-tx-state  { pins = "gpio30"; function = "qup07"; };
qup_uart7_rx:  qup-uart7-rx-state  { pins = "gpio31"; function = "qup07"; };
```

**QUPAC access control:**

```c theme={null}
// 4-wire HS UART
{ QUPV3_0_SE7, QUPV3_PROTOCOL_UART_4W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }

// 2-wire UART (no flow control)
{ QUPV3_0_SE5, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, FALSE, FALSE }
```

## Kernel Configuration

Edit `kernel_platform/kernel/arch/arm64/configs/qcom_defconfig`:

```
CONFIG_QCOM_GENI_SE=y
CONFIG_SERIAL_QCOM_GENI=y
```

Enable the UART node in the device tree:

```diff theme={null}
+serial1 = &uart7;

+&uart7 {
+    status = "ok";
+};
```

## Verification

<Steps>
  <Step title="Verify UART device registration">
    ```bash theme={null}
    ls /dev/ttyHS*
    # Expected: /dev/ttyHS1

    dmesg | grep ttyH
    # Expected: 99c000.serial: ttyHS1 at MMIO 0x99c000 ...
    ```
  </Step>

  <Step title="Configure UART settings">
    ```bash theme={null}
    stty -F /dev/ttyHS1 115200
    ```
  </Step>

  <Step title="Run loopback test">
    Open two SSH terminals.

    **Terminal 1 (write):**

    ```bash theme={null}
    echo "Hello UART" > /dev/ttyHS1
    ```

    **Terminal 2 (read):**

    ```bash theme={null}
    cat /dev/ttyHS1
    ```

    Expected output: `Hello UART`
  </Step>
</Steps>

## Debugging

### Enable Debug Logs

```bash theme={null}
mount -t debugfs none /sys/kernel/debug

echo -n "file qcom_geni_serial.c +p" > /sys/kernel/debug/dynamic_debug/control
echo -n "file qcom-geni-se.c +p" > /sys/kernel/debug/dynamic_debug/control
echo -n "file serial_core.c +p" > /sys/kernel/debug/dynamic_debug/control

dmesg | grep -i uart
dmesg | grep ttyHS
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="UART Device Not Detected (/dev/ttyHS* missing)">
    ```bash theme={null}
    lsmod | grep qcom_geni
    cat /proc/device-tree/soc@0/geniqup@*/serial*/status
    ls -la /dev/tty*
    ```

    * Verify device tree status is `"ok"`
    * Confirm `CONFIG_SERIAL_QCOM_GENI=y` in kernel config
    * Check GPIO pin configurations and QUPAC access control settings
  </Accordion>

  <Accordion title="Data Transmission Failures / Garbled Data">
    ```bash theme={null}
    # Check current UART config
    stty -F /dev/ttyHS1 -a

    # Set baud rate
    stty -F /dev/ttyHS1 115200

    # Enable/disable hardware flow control
    stty -F /dev/ttyHS1 crtscts    # enable
    stty -F /dev/ttyHS1 -crtscts   # disable
    ```

    * Verify baud rate matches on both ends
    * Check flow control configuration (CTS/RTS)
    * Test with loopback mode first
  </Accordion>

  <Accordion title="Permission Denied">
    ```bash theme={null}
    ls -la /dev/ttyHS*
    usermod -a -G dialout $USER
    ```
  </Accordion>

  <Accordion title="High CPU Usage / Slow Transfer">
    * Switch from FIFO to DMA mode for high-speed transfers
    * Check interrupt statistics: `cat /proc/interrupts | grep uart`
    * Review power management: `cat /sys/kernel/debug/pm_genpd/pm_genpd_summary`
  </Accordion>
</AccordionGroup>

### Debugging Checklist

* [ ] Kernel config includes `CONFIG_SERIAL_QCOM_GENI=y`
* [ ] Device tree status set to `"ok"` for UART node
* [ ] GPIO pins properly configured and mapped
* [ ] QUPAC access control properly configured
* [ ] Baud rate matches on both sides
* [ ] Flow control settings are consistent
* [ ] Device file permissions are correct

## Resources

* [Linux Kernel Device Tree Bindings](https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/serial/qcom%2Cserial-geni-qcom.yaml)
* [UART Driver Source](https://github.com/torvalds/linux/blob/master/drivers/tty/serial/qcom_geni_serial.c)
* [Serial Console Documentation](https://docs.kernel.org/admin-guide/serial-console.html)
