This page describes the current development efforts to port the upstream Linux Kernel to the LG Nexus 5 (hammerhead) phone. This work benefits other devices that use the Qualcomm msm8974 System on Chip (SoC) such as the Fairphone 2, OnePlus One, Samsung Galaxy S5, Sony Xperia Z1, Sony Xperia Z2 tablets, and current devices that use some of the same IP blocks within newer Qualcomm SoCs.
The factory kernel image is based on the upstream Linux 3.4 kernel that was released in May 2012, and adds almost 2 million lines of code on top of the upstream kernel. This factory image is abandoned and no longer receives security updates. The goal is to eventually get all of the major components working upstream so that the phone will work with the latest upstream kernel. These patches will eventually appear in the Android kernels as they rebase their kernels onto newer upstream LTS kernel releases.
Hardware status
The following components work upstream without any additional patches: display, backlight, touchscreen, USB, WiFi, charger, gyroscope / accelerometer, magnetometer, temperature / humidity / barometer, proximity / ambient light sensor (ALS), serial console, battery.
My linux tree on GitHub contains work-in-progress patches that adds support for the GPU, modem, bluetooth, and vibrator. See my v5.5 patch series cover letter that gives a high-level overview of the status of those patches.
I have work in progress patches available below to get the external display over HDMI and the IOMMU, where the latter is the last piece that’s needed to support the GPU upstream. The hardware isn’t fully working yet with these patches.
See the TODO list for information about other components and links to some out-of-tree patches.
Note that the kernel command line arguments msm.allow_vram_carveout msm.vram=48m
must be passed
used in order for the display to work properly. These options are present in my
build-kernel script.
Phone user space
I’ve been running postmarketOS on the phone. Follow the instructions on their Nexus 5 page that describes how to install it. Here’s my pmbootstrap.cfg config file. Once that’s installed, see my build-kernel script for how to build and boot a custom kernel into a postmarketOS userspace.
A serial console can be obtained through the headphone jack and requires building a custom cable as described on this page. You will want to make a cable if you plan to do any development work.
See the gpio_demoy.py script for the source code to the GTK+ application controlling the external LEDs in the image above. The phone is running XFCE4 and postmarketOS on an upstream Linux kernel. This Tiny OTG USB adapter is used on that video.
Upstream contribution summary
The following is a summary of my upstream Linux kernel contributions as part of this project:
- Created a new Qualcomm msm8974 interconnect driver that allows setting system bandwidth requirements between various network-on-chip fabrics. This is required in order to support the display, GPU and various other devices upstream. Patches
- Created a new On Chip Memory (OCMEM) allocator driver that allows various clients to allocate memory from OCMEM based on performance, latency and power requirements. This is typically used by the GPU, camera/video, and audio components on some Snapdragon SoCs. Patches
- Hierarchical IRQ chip support for all Qualcomm platforms (spmi-gpio and ssbi-gpio) so that device tree consumers can request an IRQ directly from the GPIO block rather than having to request an IRQ from the underlying PMIC. Contributed to the generic implementation in the GPIO core. Patches
- When attempting to setup up a GPIO hog, device probing would repeatedly fail with -EPROBE_DEFERED errors during system boot due to a circular dependency between the GPIO and Pinctrl frameworks. Patches
- Corrected issue with the Freedreno DRM/KMS driver not working properly on old command-mode DSI panels, dirty framebuffer helper support, corrected msm8974 gfx3d clock, wired display into msm8974 device tree, corrected issues when running without an IOMMU, and silenced several -EPROBE_DEFER warnings. Patches
- Created PLL driver and necessary device tree changes for external display over HDMI (work in progress), converted analogix-anx78xx driver to use i2c_new_dummy_device(), added necessary regulator node to device tree, and added support for new variants to the analogix-anx78xx driver. Patches
- Took over maintainership of the TAOS tsl2772 driver upstream for the proximity detection and ambient light sensing, performed the staging graduation, corrected equations and timings for the 10 hardware variants supported by the driver, got interrupt and proximity functionality working properly, added regulator support, and numerous cleanups to the driver. Patches
- Added firmware node support to the existing lm3630a driver and corrected an issue updating the brightness level via sysfs. Patches
- Added extcon support to the existing bq24190_charger driver upstream, and support for USB OTG to device tree. Patches
- Found and fixed an issue with the qcom-crypto.c driver not waiting for availablity of randomness from the hardware and would return zeros. Patches
- Work in progress patches to get the vibrator supported upstream. Working with the upstream maintainers to see where this code should go upstream. Patches
- Work in progress patches to get the IOMMU for the display and GPU working. Patches
- Cleaned up patches from other people and got them accepted upstream for the following components: various I2C sensors, panel, WiFi / Bluetooth, touchscreen, and sdhci.
- Bisected bugs found in linux-next with the regulator subsystem and the mmc/sdhci system.
- I have another page that describes some of my other kernel work that’s not related to this Nexus 5 project. A few highlights: 3 staging graduations in the IIO subsystem, runtime power management, and various other driver cleanups.
Patches
Note that the ones with a short git SHA at the beginning are in the mainline kernel, the ones marked Queued are in linux-next, and the others are labeled either Pending or Needs work.
-
Qualcomm MSM8974 interconnect driver that allows setting system bandwidth requirements between various network-on-chip fabrics. This is required in order to support the display, GPU and various other devices upstream. Patches
- 6120e5d821c0 (“dt-bindings: interconnect: qcom: add msm8974 bindings”)
- 4e60a9568dc6 (“interconnect: qcom: add msm8974 driver”)
- b435f8b4f6a0 (“dt-bindings: drm/msm/gpu: document second interconnect”)
- 00bb9243d346 (“drm/msm/gpu: add support for ocmem interconnect path”)
- d163ba0b65f2 (“drm/msm/a3xx: set interconnect bandwidth vote”)
- 21f5a6c08b17 (“drm/msm/a4xx: set interconnect bandwidth vote”)
- 98073faf9f15 (“ARM: dts: qcom: msm8974: add interconnect nodes”)
- ff9f2ad403c2 (“ARM: qcom_defconfig: add msm8974 interconnect support”)
-
The On Chip Memory (OCMEM) allocator allows various clients to allocate memory from OCMEM based on performance, latency and power requirements. This is typically used by the GPU, camera/video, and audio components on some Snapdragon SoCs.
- 957fd69d396b (“dt-bindings: soc: qcom: add On Chip MEMory (OCMEM) bindings”)
- 198a72c8f9ee (“dt-bindings: display: msm: gmu: add optional ocmem property”)
- 88c1e9404f1d (“soc: qcom: add OCMEM driver”)
- 26c0b26dcd00 (“drm/msm/gpu: add ocmem init/cleanup functions”)
- bfcb7e1555ec (“soc: qcom: ocmem: add missing includes”)
- a2cc991ed634 (“ARM: dts: qcom: msm8974: add ocmem node”)
- b2181be1cfb8 (“ARM: qcom_defconfig: add ocmem support”)
- b0a1614fb1f5 (“firmware: qcom: scm: add OCMEM lock/unlock interface”)
- 0434a4061471 (“firmware: qcom: scm: add support to restore secure config to qcm_scm-32”)
- 00d9220ec5ed (“dt-bindings: display: msm: gmu: move sram property to gpu bindings”)
-
Hierarchical IRQ chip support for all Qualcomm platforms (spmi-gpio and ssbi-gpio) so that device tree consumers can request an IRQ directly from the GPIO block rather than having to request an IRQ from the underlying PMIC. Contributed to the generic implementation in the GPIO core.
- 697818f383fc (“dt-bindings: pinctrl: qcom-pmic-gpio: add qcom,pmi8998-gpio binding”)
- d7ee4d0a6731 (“pinctrl: qcom: spmi-gpio: add support for three new variants”)
- cfacef373505 (“pinctrl: qcom: spmi-gpio: hardcode IRQ counts”)
- 12a9eeaebba3 (“spmi: pmic-arb: convert to v2 irq interfaces to support hierarchical IRQ chips”)
- ef74f70e5a10 (“gpio: add irq domain activate/deactivate functions”)
- 682aefaa81e6 (“spmi: pmic-arb: disassociate old virq if hwirq mapping already exists”)
- ca69e2d165eb (“qcom: spmi-gpio: add support for hierarchical IRQ chip”)
- 5f540fb4821a (“ARM: dts: qcom: pm8941: add interrupt controller properties”)
- c9a0ef552894 (“ARM: dts: qcom: pma8084: add interrupt controller properties”)
- a61326c076f2 (“arm64: dts: qcom: pm8005: add interrupt controller properties”)
- a1738363e41a (“arm64: dts: qcom: pm8998: add interrupt controller properties”)
- 8cff9c8a7881 (“arm64: dts: qcom: pmi8994: add interrupt controller properties”)
- f14a5e6da4a5 (“arm64: dts: qcom: pmi8998: add interrupt controller properties”)
- e7dc6af82c28 (“spmi: pmic-arb: revert “disassociate old virq if hwirq mapping already exists””)
- 760a160e8b89 (“pinctrl: qcom: spmi-gpio: select IRQ_DOMAIN_HIERARCHY in Kconfig”)
- 5c713d9394f3 (“spmi: pmic-arb: select IRQ_DOMAIN_HIERARCHY in Kconfig”)
- 38f7ae9bdfb6 (“genirq: export irq_chip_set_wake_parent symbol”)
- 86291029e97e (“pinctrl: qcom: ssbi-gpio: hardcode IRQ counts”)
- b5c231d8c803 (“genirq: introduce irq_domain_translate_twocell”)
- 3324a7c1a227 (“mfd: pm8xxx: convert to v2 irq interfaces to support hierarchical IRQ chips”)
- ee08e24c2e76 (“mfd: pm8xxx: disassociate old virq if hwirq mapping already exists”)
- 9d2b563bc23a (“qcom: ssbi-gpio: add support for hierarchical IRQ chip”)
- e2f6c8881287 (“arm: dts: qcom: apq8064: add interrupt controller properties”)
- a796fab2c605 (“arm: dts: qcom: msm8660: add interrupt controller properties”)
- 582648f5ef14 (“arm: dts: qcom: mdm9615: add interrupt controller properties”)
- 1a25d59a5529 (“mfd: pm8xxx: revert “disassociate old virq if hwirq mapping already exists””)
- de744e01aa3a (“mfd: pm8xxx: select IRQ_DOMAIN_HIERARCHY in Kconfig”)
- 79890c2ec486 (“qcom: ssbi-gpio: correct boundary conditions in pm8xxx_domain_translate”)
- fdd61a013a24 (“gpio: Add support for hierarchical IRQ domains”)
- 821c76c4c374 (“qcom: spmi-gpio: convert to hierarchical IRQ helpers in gpio core”)
- ae436fe81053 (“qcom: ssbi-gpio: convert to hierarchical IRQ helpers in gpio core”)
-
When attempting to setup up a gpio hog, device probing would repeatedly fail with -EPROBE_DEFERED errors during system boot due to a circular dependency between the gpio and pinctrl frameworks. This fix is required in order to support USB on the Nexus 5 since one GPIO pin needs to be hogged high at startup on the Nexus 5.
- 149a96047237 (“pinctrl: qcom: spmi-gpio: fix gpio-hog related boot issues”)
- 7ed078557738 (“pinctrl: qcom: ssbi-gpio: fix gpio-hog related boot issues”)
- cdd3d64d843a (“ARM: dts: qcom: pm8941: add gpio-ranges”)
- 33984dd6c4bb (“ARM: dts: qcom: apq8064: add gpio-ranges”)
- 3bc5163ebbac (“ARM: dts: qcom: mdm9615: add gpio-ranges”)
- 546f72e7ecb2 (“ARM: dts: qcom: msm8660: add gpio-ranges”)
- 05d86a0ae83b (“ARM: dts: qcom: pma8084: add gpio-ranges”)
- 136e9d920dc6 (“arm64: dts: qcom: pm8005: add gpio-ranges”)
- 99c70e728623 (“arm64: dts: qcom: pm8998: add gpio-ranges”)
- 21750eb93ea9 (“arm64: dts: qcom: pmi8994: add gpio-ranges”)
- d1fe337337ed (“arm64: dts: qcom: pmi8998: add gpio-ranges”)
-
Display is supported by the msm drm/kms driver upstream.
- 2bab52af6fe6 (“drm/msm: add support for per-CRTC max_vblank_count on mdp5”)
- 648fdc3f6475 (“drm/msm: add dirty framebuffer helper”)
- 5a9fc531f6ec (“ARM: dts: msm8974: add display support”)
- 489bacb29818 (“ARM: dts: qcom: msm8974-hammerhead: add support for display”)
- e2f597a20470 (“drm/msm: remove resv fields from msm_gem_object struct”)
- d67f1b6d0e0b (“drm/msm: correct attempted NULL pointer dereference in put_iova”)
- 90f94660e531 (“drm/msm: correct attempted NULL pointer dereference in debugfs”)
- 7af5cdb158f3 (“drm/msm: correct NULL pointer dereference in context_init”)
- add5bff4aa76 (“drm/msm/phy/dsi_phy: silence -EPROBE_DEFER warnings”)
- fd6c798b58e0 (“drm/msm/hdmi: silence -EPROBE_DEFER warning”)
- ef7a5baf64ce (“ARM: qcom_defconfig: add display-related options”)
- bb9b9cde0fe0 (“clk: qcom: mmcc8974: move gfx3d_clk_src from the mmcc to rpm”)
- ef8c9809acb0 (“drm/msm/mdp5: rate limit pp done timeout warnings”)
- fe079442db63 (“ARM: dts: qcom: msm8974: add gpu support”)
-
An external monitor can be hooked up via the Analogix 7808 HDMI bridge using a SlimPort cable. I’m currently using an ‘Analogix Semiconductor SP6001 SlimPort Micro-USB to 4K HDMI Adapter’.
- ac242e2cfd14 (“ARM: dts: qcom: pm8941: add 5vs2 regulator node”)
- 2f932367d219 (“drm/bridge: analogix-anx78xx: convert to i2c_new_dummy_device”)
- 025910db8057 (“drm/bridge: analogix-anx78xx: add support for 7808 addresses”)
- 2fb658a603ba (“dt-bindings: drm/bridge: analogix-anx78xx: add new variants”)
- 0273831882c5 (“drm/bridge: analogix-anx78xx: add new variants”)
- 2708e876272d (“drm/bridge: analogix-anx78xx: silence -EPROBE_DEFER warnings”)
- dd973b89ebba (“ARM: qcom_defconfig: add anx78xx HDMI bridge support”)
- Needs work: drm/bridge: analogix-anx78xx: add support for avdd33 regulator
- Needs work: drm/msm/hdmi: add msm8974 PLL support
- Needs work: ARM: dts: qcom: msm8974: add HDMI nodes
- Needs work: ARM: dts: qcom: msm8974-hammerhead: add support for external display
-
The phone contains an Avago APDS 9930 proximity / ambient light sensor (ALS), which is register compatible with the TAOS tsl2772 sensor. By mere coincidence, the tsl2772.c driver is one of the staging cleanups that I did and it took 74 patches to move that driver out of staging and into mainline. A few notable patches from that work:
- 498efcd08114 (“staging: iio: tsl2x7x: correct integration time and lux equation”)
- 9861d2daaf28 (“staging: iio: tsl2x7x: correct IIO_EV_INFO_PERIOD values”
- 2ab5b7245367 (“staging: iio: tsl2x7x: make proximity sensor function correctly”)
- 19422bde046a (“staging: iio: tsl2x7x: use auto increment I2C protocol”)
- 9e4701eaef02 (“staging: iio: tsl2x7x: correct interrupt handler trigger”)
- 77b69a0e679b (“staging: iio: tsl2x7x: convert to use read_avail”)
- 95d22154d6bb (“staging: iio: tsl2x7x: don’t setup event handlers if interrupts are not configured”)
- deaecbef3664 (“staging: iio: tsl2x7x: migrate *_thresh_period sysfs attributes to iio_event_spec”)
- 4546813a7f6b (“staging: iio: tsl2x7x: migrate in_illuminance0_integration_time sysfs attribute to iio_chan_spec”)
- a2fdb4e1a6c8 (“staging: iio: tsl2x7x: use either direction for IIO_EV_INFO_{ENABLE,PERIOD}”)
- 2f58efa96373 (“staging: iio: tsl2x7x: move integration_time* attributes to IIO_INTENSITY channel”)
- bce075d0ec4b (“staging: iio: tsl2x7x: simplify tsl2x7x_prox_cal()”)
- c06c4d793584 (“staging: iio: tsl2x7x/tsl2772: move out of staging”)
Once the staging cleanup was done, additional changes were required upstream in order to support the Nexus 5.
- 94cd1113aaa0 (“iio: tsl2772: add support for reading proximity led settings from device tree”)
- 75de3b570b1c (“iio: tsl2772: add support for avago,apds9930”)
- 7c14947e4d3d (“iio: tsl2772: add support for regulator framework”)
- bd9392507588 (“ARM: dts: qcom: msm8974-hammerhead: add device tree bindings for ALS / proximity”)
- 1ed80a817bc4 (“dt-bindings: iio: tsl2772: add new bindings”)
- 28b6977e089d (“dt-bindings: iio: tsl2772: add binding for avago,apds9930”)
- 17b62779cbe4 (“dt-bindings: iio: tsl2772: convert bindings to YAML format”)
-
The phone contains a TI lm3630a for the LCD backlight.
- d3f48ec0954c (“backlight: lm3630a: return 0 on success in update_status functions”)
- 32fcb75c66a0 (“dt-bindings: backlight: add lm3630a bindings”)
- 8fbce8efe15c (“backlight: lm3630a: add firmware node support”)
- ef4db28c1f45 (“dt-bindings: backlight: lm3630a: correct schema validation”)
- 030b6d48ebfb (“ARM: dts: qcom: msm8974-hammerhead: add support for backlight”)
-
The phone contains a BQ24192 for the charger, system power path management, and for USB OTG support. This requires the GPIO hogging patches on this page.
- 161a2135e082 (“power: supply: bq24190_charger: add extcon support for USB OTG”)
- 8e49c0b4bbe9 (“dt-bindings: power: supply: bq24190_charger: add bq24192 and usb-otg-vbus”)
- 5ea67bb0b090 (“power: supply: bq24190_charger: add support for bq24192 variant”)
- 74d09c927cb6 (“power: supply: bq24190_charger: add of_match for usb-otg-vbus regulator”)
- fb143fcbb9ad (“ARM: dts: qcom: msm8974-hammerhead: add USB OTG support”)
- 817bbbb7749d (“ARM: qcom_defconfig: add support for USB networking”)
-
The phone contains the Qualcomm Crypto Engine and the kernel driver contained a bug where it would not properly wait for the availablity of randomness from the hardware and would return zeros.
-
Add support for clock-based vibrator devices where the speed can be controlled by changing the duty cycle. Use rumble-test.c to test the driver.
-
Work in progress patches to get the IOMMU working.
- Tracked down issue with the qcom iommu driver not loading properly during a probe deferal. See this thread for details.
- Needs work: ARM: dts: qcom: msm8974: add mdp5 iommu support
-
The InvenSense mpu6515 gyroscope / accelerometer, Asahi Kasei ak8963 magnetometer, and Bosch bmp280 temperature / humidity / barometer only required minimal changes in order to support these devices on the phone.
- de8df0b9c38d (“iio: imu: mpu6050: add support for 6515 variant”)
- 07c12b1c007c (“iio: imu: mpu6050: add support for regulator framework”)
- 703e699dbe2c (“ARM: dts: qcom-msm8974: change invalid flag IRQ NONE to valid value”)
- fe8d81fe7d9a (“ARM: dts: qcom: msm8974-hammerhead: add device tree bindings for mpu6515”)
- 0567022c019a (“ARM: dts: qcom: msm8974-hammerhead: correct gpios property on magnetometer”)
- d2b863baf1c7 (“iio: pressure: bmp280: remove unused options from device tree documentation”)
-
The phone has a Broadcom (now Cypress) 4339 for wireless and bluetooth.
- 726a117628d6 (“ARM: dts: qcom: msm8974: add blsp2_uart10”)
- 231cb93c06ac (“ARM: dts: qcom: msm8974-hammerhead: add support for bluetooth”)
- ee43b5ab850f (“ARM: qcom_defconfig: add Broadcom bluetooth options”)
- ec4c6c57af57 (“ARM: dts: qcom: msm8974-hammerhead: add WiFi support”)
- Bisected an issue in 5.2rc1 that caused WiFi to stop working. This issue was fixed by the patch 89f3c365f3e1 (“mmc: sdhci: Fix SDIO IRQ thread deadlock”).
-
- 03864e57770a (“ARM: dts: qcom: msm8974-hammerhead: increase load on l20 for sdhci”) - Corrects an issue where the phone would not boot properly when starting to read from the flash memory.
- Bisected an issue in linux-next related to a change in the regulator framework that caused the the phone to no longer boot. The issue was resolved by commit fa94e48e13a1a (“regulator: core: Apply system load even if no consumer loads”.
- acd92c5a1149 (“ARM: qcom_defconfig: add options for LG Nexus 5 phone”)
- 889b94dbc553 (“ARM: qcom_defconfig: enable debug fs support”)
Other resources
- TODO list for upstreaming the various major components.
- My linux branches that include some of my in progress and out-of-tree patches.
- A full teardown of the Nexus 5 is available on ifixit.
- Downstream MSM 3.4 kernel sources with additions from the community. Use hammerhead_defconfig when building this kernel.
- postmarketOS for the Nexus 5
- Sep 2019: Linaro Connect San Diego: Status update on Qualcomm upstreaming
- Aug 2019: Mainline status update for the Nexus 5 phone (qcom msm8974 SoC)
- June 2019: Two years of postmarketOS blog post.