Qualcomm Snapdragon 845 (SDM845)

SDM845 (or Snapdragon 845) is a Qualcomm SoC released in 2018, with mainline support originally added for the Dragonboard 845c. It is currently one of the fastest mobile SoCs booting Mainline with full support for hardware accelerated graphics, CPU frequency scaling and wifi/bluetooth, with more features on the way.

Join Us!
If you own an SDM845 device and want to get postmarketOS & mainline booting, head over to the #mainline:postmarketos.org postmarketOS mainline channel.

We also discuss packaging, other distros and various other non-porting stuff on matrix: #sdm845:postmarketos.org.

Feel free to ping @caleb:postmarketos.org.

Adding yours
If you have an SDM845 based device that isn't in this list you should definitely do something about that, checkout the SDM845 Mainlining Guide for instructions on porting new devices. It is fairly straightforward to get core functionality working on most devices.

Audio
The kernel side audio stuff is mostly functional on SDM845.


 * Support for OnePlus 6 added here
 * Hack needed to fix the OnePlus 6 speaker (WHY???)

Modem
The modem is booted by the Q6V5 MSS Peripheral Image Loader, it is required to boot the WiFi adapter. It is exposed via the QRTR_NET layer, a custom shared memory transport layer developed by Qualcomm. Over this the standard QMI interface is exposed. ModemManager has great support for QRTR and thus it is possible to send/receive SMS, use mobile data and make calls.

Wakeups
Wakeups are a concept in the Linux kernel referring to a specific device or subdevice that can cause the system to exit suspend, usually via an interrupt. A good example of this is the power button, when pressed it fires an interrupt, and because that interrupt is denoted as a "wakeirq" (an interrupt that when fired _should_ wake the system from suspend) that's exactly what happens.

Context
Qualcomm platforms currently (at least as far back as SDM845) don't have a real suspend mode. The closest we get is suspend to idle (s2idle), this has the kernel freeze all of userspace and almost all kernel threads. In s2idle, peripherals (e.g. the touchscreen) can be powered down, the CPU timers (which usually fire periodic interrupts) are disabled, and the CPUs are able to spend the majority of their time in their lowest idle states. This isn't enough to enable a device to go for days at a time without charging, but it is more than enough to get through a single day at least.

When in s2idle, all interrupts are disabled with two exceptions: (enabled) wakeirqs, and irqs with the  flag. Wakeirqs may not always be enabled, for example if your touchscreen has a double tap to wake feature then the driver would denote its IRQ as "wakeup capable", this associated a "wakeup" with the interrupt. The wakeup can then be enabled via sysfs or in the driver somewhere. If a wakeup capable interrupt doesn't have its wakeup feature enabled then the irq will be disabled during s2idle.

The  flag enables a driver to run its interrupt handler and process interrupts while the kernel is in s2idle. This is useful for some essential housekeeping duties that have to happen even when the user isn't interacting with the device.

Glink
Glink is a communication mechanism used by Qualcomm SoCs to enable communication between the different processors (e.g. the Modem, Audio/Compute DSPs and Sensor DSP). It is a peer to peer system based on shared memory, every pair of processors (e.g. the AP (Linux) and Modem) have their own glink edge made up of a shared memory region and a pair of interrupts, one on the modem side and one for us. To provide a very simplified explanation: data is sent and received by finding a free "bucket" in the shared memory region, putting your data in the bucket, and then triggering an interrupt on the other side.

Glink is a kind of mesh network where (for the most part) every processor is connected to every other. It represents the "Link Layer".

The Glink driver makes use of the  flag, meaning that even when in s2idle the kernel will still process interrupts from Glink. This allows for pending messages to be handled and queued up for userspace where they might otherwise be missed.

QRTR
On top of glink is the protocol layer, QRTR (Pronounced Q-Router). QRTR is a socket-based network protocol that allows for a much higher level of communication. Each processor can expose services over the QRTR network, programs on other processors can connect to and utilise these services. For example, the modem provides a Wireless Data Service for configuring a mobile data connection, the Sensor DSP also provides its own service for retreiving sensor data (See Qualcomm_Snapdragon_Sensor_Core).

QRTR represents the "Internet Layer", performing routing and session management.

QMI
QMI is a TLV (Type-Length-Value) binary format. It predates QRTR and is quite common in modems. It serves as the transport layer, however it also defines what messages can be sent/received and how the messages are formatted. QMI is the only mechanism used by ModemManager to communicate with the modem to initiate calls, send SMS, retrieve SIM and signal status information, cell tower information, etc. An incoming call or SMS is signalled by the modem sending a QMI message.

In summary
Walking back down the stack, when you receive a phone call, the modem will check that you have an active QRTR session with it (this will be the case if ModemManager hasn't explicitly closed the connection) which is subscribed to incoming calls. It will send a QMI message to notify ModemManager. It goes roughly as follows:

1. The message is transported over QRTR and sent via Glink. 2. The Glink interrupt will fire and run the interrupt handler in the kernel. 3. The interrupt handler reads the message and passes it on the QRTR protocol implementation in the kernel. 4. The QRTR net code queues it up to be received by userspace on the next poll

This is all well and good, however when we're in s2idle, userspace is frozen, there's no way to handle the message, figure out that it's a call, and make the phone ring.

Waking up for calls and SMS
Without a way to properly differentiate between a signal strength change and an incoming call, it isn't possible for the kernel to know which messages from the modem should cause a wakeup, and which should not. All we have is a global switch.

The ideal solution here is that ModemManager becomes capable of disabling all non-essential notifications from the modem before the device suspends, this ought(?) to be possible but it's unclear how hard it would be.

For now, you can make sure that you never miss a call by waking up for every incoming message from the modem. This would be acceptable if it were possible to do this without immediately turning on the display, and if the message isn't a call or SMS, automatically suspending again. For Phosh, I believe this requires support to be added to GNOME session daemon to wake up without turning on the display. Figuring out why the device woke up (maybe it was a power button press or USB cable insertion) requires keeping track of all the counts in  and then having a look up table for each wakeup (to know that e.g. wakeup   is associated with the power button)

You can enable this wakeup for yourself by running the following command as root:

echo enabled > /sys/bus/rpmsg/devices/4080000.remoteproc:glink-edge.IPCRTR.-1.-1/power/wakeup

This will cause the device to wake up for all incoming data from the modem.

Waking up for notifications
When on a mobile data connection, the IPA (Qualcomm dedicated network packet routing hardware) will wake up the device by default for any incoming data, this usually has no effect as most TCP connections have a relatively short TCP keepalive time. However the plan is to disable it by default for now (see ) to avoid any confusion.

The IPA has the ability to maintain a TCP connection and perform some arbitrary filtering to avoid waking up the device for things that aren't notifications, e.g. matching on source IP or specific magic bytes in the packet. Unfortunately the mainline kernel driver doesn't yet implement any of these features.

The Wifi on SDM845 is ath10k and includes full Wake-On-WLAN (WoWLAN) support! Using the  utility it's possible to enable waking up on actions like wifi disconnect, specific SSIDs becoming available, or via packet matching based on source/destination IP, magic bytes, etc.

Ath10k hardware supports offloading station keepalive, where it will send null packets to whatever AP your device is connected to in order to ensure that it doesn't get dropped. However this feature is explicitly disabled (via This patch) in favour of software polling, perhaps worth reinvestigating!

A notification push client service could be taught how to utilise WoWLAN and the IPA to maintain a persistent TCP connection with the server and cause the device to wake up for incoming notifications. It should be possible to also implement automatic switching between mobile data and wifi, between wifi networks, and between mobile cell towers. WoWLAN can wake up on wifi disconnect, and the modem can wake up when switching cell tower, allowing the connection to be re-established. A very long keepalive time will ensure that it doesn't drop for some other reason.

WiFi
Wifi is functional! Firmware for the modem and ath10k module must be loaded in order to have functional wifi.

3 packages are required for functional wifi:

rmtfs, pd-mapper and tqftpserv can be installed with

.

This readme can then be followed to fixup the firmware.

Some devices need this quirk enabled for ath10k probe to succeed.

More details may also be found on the Snapdragon 835 SoC page.

Display
The Adreno 630 is relatively easy to work with, after adding a driver for your panel, obtain the firmware from your device and either compile into the kernel (in addition to enabling CONFIG_DRM_FBDEV_EMULATION for early dmesg)) or add to the right subdirectory under /lib/firmware.

I2C
I2C and the Geni hardware is functional and supported, however it is missing a driver for special GPI DMA mode used by a few devices (e.g. touchscreen on Enchilada). As of 5.11-rc1 geni is capable of DMA, however not through the GPI hardware. The issues previously discussed here no longer apply.


 * WIP GPI DMA driver in mainline: https://patchwork.kernel.org/patch/11732405/

Bluetooth
Bluetooth works!

Haptics
Haptics is supported! See Haptics for more details.

Renegade Project
Renegade Project support some sdm845 device

uboot
In progress u-boot port exists

Who's working on it

 * User:kalube (@caleb:postmarketos.org on Matrix)
 * User:venji10 (@venji10 on Matrix)
 * User:Joel (@jo:jsfamily.in on Matrix)
 * User:Dsankouski (@dsankouski on Matrix) - u-boot porting for Samsung_Galaxy_S9_(samsung-starqltechn)
 * 'And more...'