aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2017-03-04 19:37:50 +0100
committerÁlvaro Fernández Rojas <noltari@gmail.com>2017-03-04 19:37:50 +0100
commitbaad22eed3ea3242051bbde6ebf56e74deb11ea6 (patch)
tree2980f26a82772c37d7d655871780fad0f3a4aeb1 /target/linux
parentf229f4af31731badc2dec27c9bdef9f5fa8f7433 (diff)
downloadupstream-baad22eed3ea3242051bbde6ebf56e74deb11ea6.tar.gz
upstream-baad22eed3ea3242051bbde6ebf56e74deb11ea6.tar.bz2
upstream-baad22eed3ea3242051bbde6ebf56e74deb11ea6.zip
brcm2708: update linux 4.9 patches to latest version
As usual these patches were extracted and rebased from the raspberry pi repo: https://github.com/raspberrypi/linux/tree/rpi-4.9.y - Remove led1 from diag.sh for RPi3 since it causes boot issues. - Fix modules.mk typos. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux')
-rw-r--r--target/linux/brcm2708/base-files/etc/diag.sh3
-rw-r--r--target/linux/brcm2708/bcm2708/config-4.91
-rw-r--r--target/linux/brcm2708/bcm2709/config-4.91
-rw-r--r--target/linux/brcm2708/bcm2710/config-4.91
-rw-r--r--target/linux/brcm2708/modules.mk50
-rw-r--r--target/linux/brcm2708/patches-4.9/0001-smsx95xx-fix-crimes-against-truesize.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0002-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0003-Allow-mac-address-to-be-set-in-smsc95xx.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0004-Protect-__release_resource-against-resources-without.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0005-mm-Remove-the-PFN-busy-warning.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0007-irqchip-bcm2835-Add-FIQ-support.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0008-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0010-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0011-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0012-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0013-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0014-pinctrl-bcm2835-Return-pins-to-inputs-when-freed.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0015-spi-bcm2835-Support-pin-groups-other-than-7-11.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0016-spi-bcm2835-Disable-forced-software-CS.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0017-spi-bcm2835-Remove-unused-code.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0018-ARM-bcm2835-Set-Serial-number-and-Revision.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0019-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0020-firmware-Updated-mailbox-header.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0021-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0022-rtc-Add-SPI-alias-for-pcf2123-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0023-watchdog-bcm2835-Support-setting-reboot-partition.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0024-reboot-Use-power-off-rather-than-busy-spinning-when-.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0025-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0026-Register-the-clocks-early-during-the-boot-process.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0027-bcm2835-rng-Avoid-initialising-if-already-enabled.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0028-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0029-BCM2835_DT-Fix-I2S-register-map.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0030-Main-bcm2708-bcm2709-linux-port.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0031-Add-dwc_otg-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0032-bcm2708-framebuffer-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0033-dmaengine-Add-support-for-BCM2708.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0034-MMC-added-alternative-MMC-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0035-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0036-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0037-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0038-bcm2708-alsa-sound-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0039-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0040-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0041-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0042-Add-SMI-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0043-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0044-Add-SMI-NAND-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0045-lirc-added-support-for-RaspberryPi-GPIO.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0046-Add-cpufreq-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0047-Added-hwmon-thermal-driver-for-reporting-core-temper.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0048-Add-Chris-Boot-s-i2c-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0049-char-broadcom-Add-vcio-module.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0050-firmware-bcm2835-Support-ARCH_BCM270x.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0051-bcm2835-add-v4l2-camera-device.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0052-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0053-scripts-dtc-Update-to-upstream-version-1.4.1.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0054-BCM2708-Add-core-Device-Tree-support.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0055-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0056-fbdev-add-FBIOCOPYAREA-ioctl.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0057-Speed-up-console-framebuffer-imageblit-function.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0058-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0059-Added-Device-IDs-for-August-DVB-T-205.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0060-config-Enable-CONFIG_MEMCG-but-leave-it-disabled-due.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0061-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0062-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0063-Improve-__copy_to_user-and-__copy_from_user-performa.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0064-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0065-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0066-ASoC-Add-support-for-HifiBerry-DAC.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0067-ASoC-Add-support-for-Rpi-DAC.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0068-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0069-ASoC-BCM-Add-support-for-HiFiBerry-Digi.-Driver-is-b.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0070-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0071-iqaudio-dac-Compile-fix-untested.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0072-Added-support-for-HiFiBerry-DAC.patch2
-rw-r--r--target/linux/brcm2708/patches-4.9/0073-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch29
-rw-r--r--target/linux/brcm2708/patches-4.9/0074-Revert-Added-driver-for-HiFiBerry-Amp-amplifier-add-.patch807
-rw-r--r--target/linux/brcm2708/patches-4.9/0074-Update-ds1307-driver-for-device-tree-support.patch (renamed from target/linux/brcm2708/patches-4.9/0075-Update-ds1307-driver-for-device-tree-support.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0075-Add-driver-for-rpi-proto.patch (renamed from target/linux/brcm2708/patches-4.9/0076-Add-driver-for-rpi-proto.patch)9
-rw-r--r--target/linux/brcm2708/patches-4.9/0076-RaspiDAC3-support.patch (renamed from target/linux/brcm2708/patches-4.9/0077-RaspiDAC3-support.patch)10
-rw-r--r--target/linux/brcm2708/patches-4.9/0077-Add-Support-for-JustBoom-Audio-boards.patch (renamed from target/linux/brcm2708/patches-4.9/0078-Add-Support-for-JustBoom-Audio-boards.patch)8
-rw-r--r--target/linux/brcm2708/patches-4.9/0078-ARM-adau1977-adc-Add-basic-machine-driver-for-adau19.patch (renamed from target/linux/brcm2708/patches-4.9/0079-ARM-adau1977-adc-Add-basic-machine-driver-for-adau19.patch)10
-rw-r--r--target/linux/brcm2708/patches-4.9/0079-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch (renamed from target/linux/brcm2708/patches-4.9/0080-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch)10
-rw-r--r--target/linux/brcm2708/patches-4.9/0080-Add-IQAudIO-Digi-WM8804-board-support.patch (renamed from target/linux/brcm2708/patches-4.9/0081-Add-IQAudIO-Digi-WM8804-board-support.patch)8
-rw-r--r--target/linux/brcm2708/patches-4.9/0081-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch (renamed from target/linux/brcm2708/patches-4.9/0082-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch)10
-rw-r--r--target/linux/brcm2708/patches-4.9/0082-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch (renamed from target/linux/brcm2708/patches-4.9/0083-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch)10
-rw-r--r--target/linux/brcm2708/patches-4.9/0083-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch (renamed from target/linux/brcm2708/patches-4.9/0084-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch)10
-rw-r--r--target/linux/brcm2708/patches-4.9/0084-Support-for-Blokas-Labs-pisound-board.patch (renamed from target/linux/brcm2708/patches-4.9/0085-Support-for-Blokas-Labs-pisound-board.patch)10
-rw-r--r--target/linux/brcm2708/patches-4.9/0085-rpi_display-add-backlight-driver-and-overlay.patch (renamed from target/linux/brcm2708/patches-4.9/0086-rpi_display-add-backlight-driver-and-overlay.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0086-bcm2835-virtgpio-Virtual-GPIO-driver.patch (renamed from target/linux/brcm2708/patches-4.9/0087-bcm2835-virtgpio-Virtual-GPIO-driver.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0087-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch (renamed from target/linux/brcm2708/patches-4.9/0088-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0090-OF-DT-Overlay-configfs-interface.patch (renamed from target/linux/brcm2708/patches-4.9/0091-OF-DT-Overlay-configfs-interface.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0092-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch (renamed from target/linux/brcm2708/patches-4.9/0093-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0093-config-Add-default-configs.patch (renamed from target/linux/brcm2708/patches-4.9/0094-config-Add-default-configs.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0094-Add-arm64-configuration-and-device-tree-differences.patch (renamed from target/linux/brcm2708/patches-4.9/0095-Add-arm64-configuration-and-device-tree-differences.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0095-vchiq_arm-Tweak-the-logging-output.patch (renamed from target/linux/brcm2708/patches-4.9/0096-vchiq_arm-Tweak-the-logging-output.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0096-vchiq_arm-Access-the-dequeue_pending-flag-locked.patch (renamed from target/linux/brcm2708/patches-4.9/0097-vchiq_arm-Access-the-dequeue_pending-flag-locked.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0097-vchiq_arm-Service-callbacks-must-not-fail.patch (renamed from target/linux/brcm2708/patches-4.9/0098-vchiq_arm-Service-callbacks-must-not-fail.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0098-vchiq_arm-Add-completion-records-under-the-mutex.patch (renamed from target/linux/brcm2708/patches-4.9/0099-vchiq_arm-Add-completion-records-under-the-mutex.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0099-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch (renamed from target/linux/brcm2708/patches-4.9/0100-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0100-staging-vchi-Convert-to-current-get_user_pages-argum.patch (renamed from target/linux/brcm2708/patches-4.9/0101-staging-vchi-Convert-to-current-get_user_pages-argum.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0101-staging-vchi-Update-for-rename-of-page_cache_release.patch (renamed from target/linux/brcm2708/patches-4.9/0102-staging-vchi-Update-for-rename-of-page_cache_release.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0102-drivers-vchi-Remove-dependency-on-CONFIG_BROKEN.patch (renamed from target/linux/brcm2708/patches-4.9/0103-drivers-vchi-Remove-dependency-on-CONFIG_BROKEN.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0103-raspberrypi-firmware-Export-the-general-transaction-.patch (renamed from target/linux/brcm2708/patches-4.9/0104-raspberrypi-firmware-Export-the-general-transaction-.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0104-raspberrypi-firmware-Define-the-MBOX-channel-in-the-.patch (renamed from target/linux/brcm2708/patches-4.9/0105-raspberrypi-firmware-Define-the-MBOX-channel-in-the-.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0105-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch (renamed from target/linux/brcm2708/patches-4.9/0106-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0106-i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch (renamed from target/linux/brcm2708/patches-4.9/0107-i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0107-i2c-bcm2835-Protect-against-unexpected-TXW-RXR-inter.patch (renamed from target/linux/brcm2708/patches-4.9/0108-i2c-bcm2835-Protect-against-unexpected-TXW-RXR-inter.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0108-i2c-bcm2835-Use-dev_dbg-logging-on-transfer-errors.patch (renamed from target/linux/brcm2708/patches-4.9/0109-i2c-bcm2835-Use-dev_dbg-logging-on-transfer-errors.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0109-i2c-bcm2835-Can-t-support-I2C_M_IGNORE_NAK.patch (renamed from target/linux/brcm2708/patches-4.9/0110-i2c-bcm2835-Can-t-support-I2C_M_IGNORE_NAK.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0110-i2c-bcm2835-Add-support-for-Repeated-Start-Condition.patch (renamed from target/linux/brcm2708/patches-4.9/0111-i2c-bcm2835-Add-support-for-Repeated-Start-Condition.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0111-i2c-bcm2835-Support-i2c-dev-ioctl-I2C_TIMEOUT.patch (renamed from target/linux/brcm2708/patches-4.9/0112-i2c-bcm2835-Support-i2c-dev-ioctl-I2C_TIMEOUT.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0112-i2c-bcm2835-Add-support-for-dynamic-clock.patch (renamed from target/linux/brcm2708/patches-4.9/0113-i2c-bcm2835-Add-support-for-dynamic-clock.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0113-i2c-bcm2835-Add-debug-support.patch (renamed from target/linux/brcm2708/patches-4.9/0114-i2c-bcm2835-Add-debug-support.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0114-arm64-Add-CONFIG_ARCH_BCM2835.patch (renamed from target/linux/brcm2708/patches-4.9/0115-arm64-Add-CONFIG_ARCH_BCM2835.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0115-Add-support-for-Silicon-Labs-Si7013-20-21-humidity-t.patch (renamed from target/linux/brcm2708/patches-4.9/0116-Add-support-for-Silicon-Labs-Si7013-20-21-humidity-t.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0116-Document-the-si7020-option.patch (renamed from target/linux/brcm2708/patches-4.9/0117-Document-the-si7020-option.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0117-pisound-improvements.patch (renamed from target/linux/brcm2708/patches-4.9/0118-pisound-improvements.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0118-Add-driver_name-property.patch (renamed from target/linux/brcm2708/patches-4.9/0122-Add-driver_name-property.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0119-Add-driver_name-paramater.patch (renamed from target/linux/brcm2708/patches-4.9/0123-Add-driver_name-paramater.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0119-Revert-Revert-Added-driver-for-HiFiBerry-Amp-amplifi.patch809
-rw-r--r--target/linux/brcm2708/patches-4.9/0120-BCM270X_DT-Add-pi3-disable-wifi-overlay.patch (renamed from target/linux/brcm2708/patches-4.9/0124-BCM270X_DT-Add-pi3-disable-wifi-overlay.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0120-hifiberry-amp-Adjust-for-ALSA-object-refactoring.patch25
-rw-r--r--target/linux/brcm2708/patches-4.9/0121-ARM64-Make-it-work-again-on-4.9-1790.patch (renamed from target/linux/brcm2708/patches-4.9/0125-ARM64-Make-it-work-again-on-4.9-1790.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0121-bcm2835-i2s-Changes-for-allowing-asymmetric-sample-f.patch89
-rw-r--r--target/linux/brcm2708/patches-4.9/0122-ARM64-Enable-Kernel-Address-Space-Randomization-1792.patch (renamed from target/linux/brcm2708/patches-4.9/0126-ARM64-Enable-Kernel-Address-Space-Randomization-1792.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0124-ARM64-Enable-RTL8187-RTL8192CU-wifi-in-build-config.patch (renamed from target/linux/brcm2708/patches-4.9/0128-ARM64-Enable-RTL8187-RTL8192CU-wifi-in-build-config.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0125-BCM270X_DT-Add-spi0-cs-overlay.patch (renamed from target/linux/brcm2708/patches-4.9/0129-BCM270X_DT-Add-spi0-cs-overlay.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0126-spi-bcm2835-Disable-forced-software-CS.patch (renamed from target/linux/brcm2708/patches-4.9/0130-spi-bcm2835-Disable-forced-software-CS.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0127-config-Add-CONFIG_TCP_CONG_BBR.patch (renamed from target/linux/brcm2708/patches-4.9/0131-config-Add-CONFIG_TCP_CONG_BBR.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0128-BCM270X_DT-Enable-UART0-on-CM3.patch (renamed from target/linux/brcm2708/patches-4.9/0133-BCM270X_DT-Enable-UART0-on-CM3.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0129-config-Add-CONFIG_MD_M25P80-and-CONFIG_MD_SPI_NOR.patch (renamed from target/linux/brcm2708/patches-4.9/0134-config-Add-CONFIG_MD_M25P80-and-CONFIG_MD_SPI_NOR.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0130-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch (renamed from target/linux/brcm2708/patches-4.9/0135-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0131-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch (renamed from target/linux/brcm2708/patches-4.9/0136-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0132-ARM64-Enable-DWC_OTG-Driver-In-ARM64-Build-Config-bc.patch (renamed from target/linux/brcm2708/patches-4.9/0137-ARM64-Enable-DWC_OTG-Driver-In-ARM64-Build-Config-bc.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0132-Revert-bcm2835-i2s-Changes-for-allowing-asymmetric-s.patch90
-rw-r--r--target/linux/brcm2708/patches-4.9/0133-ARM64-Use-dwc_otg-driver-by-default-for-USB.patch (renamed from target/linux/brcm2708/patches-4.9/0138-ARM64-Use-dwc_otg-driver-by-default-for-USB.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0134-BCM270X_DT-Add-reference-to-audio_pins-to-CM-dtb.patch (renamed from target/linux/brcm2708/patches-4.9/0139-BCM270X_DT-Add-reference-to-audio_pins-to-CM-dtb.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0135-config-Add-additional-network-scheduling-modules.patch (renamed from target/linux/brcm2708/patches-4.9/0140-config-Add-additional-network-scheduling-modules.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0136-ASoC-A-simple-card-overlay-for-ADAU7002.patch (renamed from target/linux/brcm2708/patches-4.9/0141-ASoC-A-simple-card-overlay-for-ADAU7002.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0137-config-Add-SND_SOC_ADAU7002-codec-module.patch (renamed from target/linux/brcm2708/patches-4.9/0142-config-Add-SND_SOC_ADAU7002-codec-module.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0138-Add-overlay-for-mcp3008-adc-1818.patch (renamed from target/linux/brcm2708/patches-4.9/0143-Add-overlay-for-mcp3008-adc-1818.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0139-usb-dwc2-Avoid-suspending-if-we-re-in-gadget-mode-18.patch (renamed from target/linux/brcm2708/patches-4.9/0144-usb-dwc2-Avoid-suspending-if-we-re-in-gadget-mode-18.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0140-gpio_mem-Remove-unnecessary-dev_info-output-1830.patch (renamed from target/linux/brcm2708/patches-4.9/0150-gpio_mem-Remove-unnecessary-dev_info-output-1830.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0141-config-Enable-regulator-support.patch (renamed from target/linux/brcm2708/patches-4.9/0145-config-Enable-regulator-support.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0142-BCM270x-DT-expose-3.3V-and-5V-system-rails.patch (renamed from target/linux/brcm2708/patches-4.9/0146-BCM270x-DT-expose-3.3V-and-5V-system-rails.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0143-BCM270x-DT-Consolidate-audio-card-overlays.patch (renamed from target/linux/brcm2708/patches-4.9/0147-BCM270x-DT-Consolidate-audio-card-overlays.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0144-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch (renamed from target/linux/brcm2708/patches-4.9/0148-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0145-config-enable-Cirrus-Logic-Audio-Card.patch (renamed from target/linux/brcm2708/patches-4.9/0149-config-enable-Cirrus-Logic-Audio-Card.patch)2
-rw-r--r--target/linux/brcm2708/patches-4.9/0146-irq-bcm2836-Avoid-Invalid-trigger-warning.patch24
-rw-r--r--target/linux/brcm2708/patches-4.9/0147-sound-Demote-deferral-errors-to-INFO-level.patch35
-rw-r--r--target/linux/brcm2708/patches-4.9/0148-sound-Suppress-error-message-about-deferrals.patch217
-rw-r--r--target/linux/brcm2708/patches-4.9/0149-Update-vfpmodule.c.patch137
-rw-r--r--target/linux/brcm2708/patches-4.9/0150-dwc_otg-fix-summarize-urb-actual_length-for-isochron.patch28
-rw-r--r--target/linux/brcm2708/patches-4.9/0151-clk-bcm2835-Fix-fixed_divider-of-pllh_aux.patch27
-rw-r--r--target/linux/brcm2708/patches-4.9/0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch124
-rw-r--r--target/linux/brcm2708/patches-4.9/0153-clk-bcm-Allow-rate-change-propagation-to-PLLH_AUX-on.patch35
-rw-r--r--target/linux/brcm2708/patches-4.9/0154-clk-bcm-Fix-maybe-uninitialized-warning-in-bcm2835_c.patch29
-rw-r--r--target/linux/brcm2708/patches-4.9/0155-clk-bcm2835-Don-t-rate-change-PLLs-on-behalf-of-DSI-.patch172
-rw-r--r--target/linux/brcm2708/patches-4.9/0156-clk-bcm2835-Register-the-DSI0-DSI1-pixel-clocks.patch238
-rw-r--r--target/linux/brcm2708/patches-4.9/0157-clk-bcm2835-Add-leaf-clock-measurement-support-disab.patch346
-rw-r--r--target/linux/brcm2708/patches-4.9/0158-drm-panel-Add-support-for-the-Raspberry-Pi-7-Touchsc.patch575
-rw-r--r--target/linux/brcm2708/patches-4.9/0159-BCM270X-Add-the-DSI-panel-to-the-defconfig.patch45
-rw-r--r--target/linux/brcm2708/patches-4.9/0160-ARM-bcm2835-dt-Add-the-DSI-module-nodes-and-clocks.patch101
-rw-r--r--target/linux/brcm2708/patches-4.9/0161-BCM270X-Enable-the-DSI-panel-node-in-the-VC4-overlay.patch138
-rw-r--r--target/linux/brcm2708/patches-4.9/0162-drm-vc4-Fix-termination-of-the-initial-scan-for-bran.patch68
-rw-r--r--target/linux/brcm2708/patches-4.9/0163-drm-vc4-Add-support-for-rendering-with-ETC1-textures.patch55
-rw-r--r--target/linux/brcm2708/patches-4.9/0164-drm-vc4-Use-runtime-autosuspend-to-avoid-thrashing-V.patch78
-rw-r--r--target/linux/brcm2708/patches-4.9/0165-drm-vc4-Add-fragment-shader-threading-support.patch228
-rw-r--r--target/linux/brcm2708/patches-4.9/0166-drm-vc4-Fix-race-between-page-flip-completion-event-.patch93
-rw-r--r--target/linux/brcm2708/patches-4.9/0167-drm-vc4-Fix-clock_select-setting-for-the-VEC-encoder.patch113
-rw-r--r--target/linux/brcm2708/patches-4.9/0168-drm-Add-TV-connector-states-to-drm_connector_state.patch148
-rw-r--r--target/linux/brcm2708/patches-4.9/0169-drm-Turn-DRM_MODE_SUBCONNECTOR_xx-definitions-into-a.patch46
-rw-r--r--target/linux/brcm2708/patches-4.9/0170-drm-vc4-Add-support-for-the-VEC-Video-Encoder-IP.patch730
-rw-r--r--target/linux/brcm2708/patches-4.9/0171-drm-vc4-Set-up-SCALER_DISPCTRL-at-boot.patch58
-rw-r--r--target/linux/brcm2708/patches-4.9/0172-drm-vc4-Add-support-for-feeding-DSI-encoders-from-th.patch113
-rw-r--r--target/linux/brcm2708/patches-4.9/0173-drm-vc4-Add-DSI-driver.patch1817
-rw-r--r--target/linux/brcm2708/patches-4.9/0174-ARM-dts-bcm283x-Add-VEC-node-in-bcm283x.dtsi.patch31
-rw-r--r--target/linux/brcm2708/patches-4.9/0175-ARM-dts-bcm283x-Enable-the-VEC-IP-on-all-RaspberryPi.patch26
-rw-r--r--target/linux/brcm2708/patches-4.9/0176-BCM270X-Disable-VEC-unless-vc4-kms-v3d-is-present.patch37
-rw-r--r--target/linux/brcm2708/patches-4.9/0177-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch24
-rw-r--r--target/linux/brcm2708/patches-4.9/0178-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch69
-rw-r--r--target/linux/brcm2708/patches-4.9/0179-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch42
-rw-r--r--target/linux/brcm2708/patches-4.9/0180-drm-vc4-Fulfill-user-BO-creation-requests-from-the-k.patch53
-rw-r--r--target/linux/brcm2708/patches-4.9/0181-drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-.patch34
-rw-r--r--target/linux/brcm2708/patches-4.9/0182-drm-vc4-Verify-at-boot-that-CMA-doesn-t-cross-a-256M.patch79
-rw-r--r--target/linux/brcm2708/patches-4.9/0183-BCM270X_DT-Add-SMSC-ethernet-controller-to-DT.patch57
-rw-r--r--target/linux/brcm2708/patches-4.9/0185-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch28
-rw-r--r--target/linux/brcm2708/patches-4.9/0186-clk-bcm2835-Add-claim-clocks-property.patch133
-rw-r--r--target/linux/brcm2708/patches-4.9/0187-dmaengine-bcm2835-Fix-cyclic-DMA-period-splitting.patch39
-rw-r--r--target/linux/brcm2708/patches-4.9/0188-Add-ads1015-driver-to-config.patch52
-rw-r--r--target/linux/brcm2708/patches-4.9/0189-config-add-slcan-kernel-module.patch31
-rw-r--r--target/linux/brcm2708/patches-4.9/0190-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch251
-rw-r--r--target/linux/brcm2708/patches-4.9/0191-SQUASH-Add-LOCO-V2-overlay-from-last-commit.patch62
-rw-r--r--target/linux/brcm2708/patches-4.9/0192-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch333
-rw-r--r--target/linux/brcm2708/patches-4.9/0193-Add-overlay-for-ads1115-ADCs-1864.patch159
-rw-r--r--target/linux/brcm2708/patches-4.9/0194-clk-bcm2835-Correct-the-prediv-logic.patch27
-rw-r--r--target/linux/brcm2708/patches-4.9/0195-amba_pl011-Round-input-clock-up.patch86
-rw-r--r--target/linux/brcm2708/patches-4.9/0196-BCM2835-V4L2-Ensure-H264-header-bytes-get-a-sensible.patch87
-rw-r--r--target/linux/brcm2708/patches-4.9/0197-BCM2835-V4L2-Correctly-denote-key-frames-in-encoded-.patch24
-rw-r--r--target/linux/brcm2708/patches-4.9/0198-bcm2835-gpio-exp-Driver-for-GPIO-expander-via-mailbo.patch405
-rw-r--r--target/linux/brcm2708/patches-4.9/0199-BCM270X_DT-Add-bcm2708-rpi-0-w.dts.patch225
203 files changed, 8458 insertions, 2012 deletions
diff --git a/target/linux/brcm2708/base-files/etc/diag.sh b/target/linux/brcm2708/base-files/etc/diag.sh
index 2a866e4339..ecc6242d73 100644
--- a/target/linux/brcm2708/base-files/etc/diag.sh
+++ b/target/linux/brcm2708/base-files/etc/diag.sh
@@ -12,8 +12,7 @@ set_state() {
status_led="led0"
;;
rpi-b-plus |\
- rpi-2-b |\
- rpi-3-b)
+ rpi-2-b)
status_led="led1"
;;
esac
diff --git a/target/linux/brcm2708/bcm2708/config-4.9 b/target/linux/brcm2708/bcm2708/config-4.9
index 1619ba941d..c1bed074c3 100644
--- a/target/linux/brcm2708/bcm2708/config-4.9
+++ b/target/linux/brcm2708/bcm2708/config-4.9
@@ -164,6 +164,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GPIOLIB=y
+# CONFIG_GPIO_BCM_EXP is not set
# CONFIG_GPIO_BCM_VIRT is not set
CONFIG_GPIO_SYSFS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
diff --git a/target/linux/brcm2708/bcm2709/config-4.9 b/target/linux/brcm2708/bcm2709/config-4.9
index dffc368eb2..0c9adec710 100644
--- a/target/linux/brcm2708/bcm2709/config-4.9
+++ b/target/linux/brcm2708/bcm2709/config-4.9
@@ -179,6 +179,7 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GPIOLIB=y
+CONFIG_GPIO_BCM_EXP=y
CONFIG_GPIO_BCM_VIRT=y
CONFIG_GPIO_SYSFS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
diff --git a/target/linux/brcm2708/bcm2710/config-4.9 b/target/linux/brcm2708/bcm2710/config-4.9
index 04d0da8f7a..e07d8cf4e6 100644
--- a/target/linux/brcm2708/bcm2710/config-4.9
+++ b/target/linux/brcm2708/bcm2710/config-4.9
@@ -191,6 +191,7 @@ CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GPIOLIB=y
+CONFIG_GPIO_BCM_EXP=y
CONFIG_GPIO_BCM_VIRT=y
CONFIG_GPIO_SYSFS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
diff --git a/target/linux/brcm2708/modules.mk b/target/linux/brcm2708/modules.mk
index e2b3fdb59e..a49f9d48b6 100644
--- a/target/linux/brcm2708/modules.mk
+++ b/target/linux/brcm2708/modules.mk
@@ -126,8 +126,8 @@ define KernelPackage/sound-soc-digidac1-soundcard
$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8741.ko \
$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko \
$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804-i2c.ko
- AUTOLOAD:=$(call AutoLoad,68,snd-soc-snd-soc-wm8741 \
- snd-soc-snd-soc-wm8804 snd-soc-snd-soc-wm8804-i2c \
+ AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8741 \
+ snd-soc-wm8804 snd-soc-wm8804-i2c \
snd-soc-digidac1-soundcard)
DEPENDS:= \
kmod-sound-soc-bcm2835-i2s \
@@ -149,7 +149,7 @@ define KernelPackage/sound-soc-dionaudio-loco
FILES:= \
$(LINUX_DIR)/sound/soc/bcm/snd-soc-dionaudio-loco.ko \
$(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm5102a.ko
- AUTOLOAD:=$(call AutoLoad,68,snd-soc-snd-soc-pcm5102a \
+ AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm5102a \
snd-soc-dionaudio-loco)
DEPENDS:= \
kmod-sound-soc-bcm2835-i2s
@@ -162,6 +162,50 @@ endef
$(eval $(call KernelPackage,sound-soc-dionaudio-loco))
+define KernelPackage/sound-soc-dionaudio-loco-v2
+ TITLE:=Support for Dion Audio LOCO-V2 DAC-AMP
+ KCONFIG:= \
+ CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2 \
+ CONFIG_SND_SOC_PCM512x \
+ CONFIG_SND_SOC_PCM512x_I2C
+ FILES:= \
+ $(LINUX_DIR)/sound/soc/bcm/snd-soc-dionaudio-loco.ko \
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x.ko \
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x-i2c.ko
+ AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x snd-soc-pcm512x-i2c \
+ snd-soc-dionaudio-loco)
+ DEPENDS:= \
+ kmod-sound-soc-bcm2835-i2s
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-dionaudio-loco-v2/description
+ This package contains support for Dion Audio LOCO-V2 DAC-AMP
+endef
+
+$(eval $(call KernelPackage,sound-soc-dionaudio-loco-v2))
+
+define KernelPackage/sound-soc-fe-pi
+ TITLE:=Support for Fe-Pi Audio Sound Card
+ KCONFIG:= \
+ CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO \
+ CONFIG_SND_SOC_SGTL5000
+ FILES:= \
+ $(LINUX_DIR)/sound/soc/bcm/snd-soc-fe-pi-audio.ko \
+ $(LINUX_DIR)/sound/soc/codecs/snd-soc-sgtl5000.ko
+ AUTOLOAD:=$(call AutoLoad,68,snd-soc-sgtl5000 \
+ snd-soc-fe-pi-audio)
+ DEPENDS:= \
+ kmod-sound-soc-bcm2835-i2s
+ $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-soc-fe-pi/description
+ This package contains support for Fe-Pi Audio Sound Card
+endef
+
+$(eval $(call KernelPackage,sound-soc-fe-pi))
+
define KernelPackage/sound-soc-hifiberry-dac
TITLE:=Support for HifiBerry DAC
KCONFIG:= \
diff --git a/target/linux/brcm2708/patches-4.9/0001-smsx95xx-fix-crimes-against-truesize.patch b/target/linux/brcm2708/patches-4.9/0001-smsx95xx-fix-crimes-against-truesize.patch
index b8b424beee..a5737e3c83 100644
--- a/target/linux/brcm2708/patches-4.9/0001-smsx95xx-fix-crimes-against-truesize.patch
+++ b/target/linux/brcm2708/patches-4.9/0001-smsx95xx-fix-crimes-against-truesize.patch
@@ -1,4 +1,4 @@
-From 3df8aa3aa981f3c463d793b69fa23c5aab53fec2 Mon Sep 17 00:00:00 2001
+From c01a3230d8cdd396dcec2619646f6cf2753481d8 Mon Sep 17 00:00:00 2001
From: Steve Glendinning <steve.glendinning@smsc.com>
Date: Thu, 19 Feb 2015 18:47:12 +0000
Subject: [PATCH] smsx95xx: fix crimes against truesize
diff --git a/target/linux/brcm2708/patches-4.9/0002-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch b/target/linux/brcm2708/patches-4.9/0002-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch
index 9d47276af6..fc7ac4d8b9 100644
--- a/target/linux/brcm2708/patches-4.9/0002-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch
+++ b/target/linux/brcm2708/patches-4.9/0002-smsc95xx-Experimental-Enable-turbo_mode-and-packetsi.patch
@@ -1,4 +1,4 @@
-From aefca8fa1aefb12cc7ac1862b4c6e94c1ec9e74c Mon Sep 17 00:00:00 2001
+From 8272cd893c3bca2f047dcf06ae11d9ada6d26f33 Mon Sep 17 00:00:00 2001
From: Sam Nazarko <email@samnazarko.co.uk>
Date: Fri, 1 Apr 2016 17:27:21 +0100
Subject: [PATCH] smsc95xx: Experimental: Enable turbo_mode and packetsize=2560
diff --git a/target/linux/brcm2708/patches-4.9/0003-Allow-mac-address-to-be-set-in-smsc95xx.patch b/target/linux/brcm2708/patches-4.9/0003-Allow-mac-address-to-be-set-in-smsc95xx.patch
index dbcf303232..8075dff2f3 100644
--- a/target/linux/brcm2708/patches-4.9/0003-Allow-mac-address-to-be-set-in-smsc95xx.patch
+++ b/target/linux/brcm2708/patches-4.9/0003-Allow-mac-address-to-be-set-in-smsc95xx.patch
@@ -1,4 +1,4 @@
-From a4774fe88b0a06562a7b6c5d3181f13e7444a3f0 Mon Sep 17 00:00:00 2001
+From 2e70eba32ed21b1a909b9ae6a06b3384a33fc5a4 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 17:26:38 +0000
Subject: [PATCH] Allow mac address to be set in smsc95xx
diff --git a/target/linux/brcm2708/patches-4.9/0004-Protect-__release_resource-against-resources-without.patch b/target/linux/brcm2708/patches-4.9/0004-Protect-__release_resource-against-resources-without.patch
index f46579b943..4b80ab0bec 100644
--- a/target/linux/brcm2708/patches-4.9/0004-Protect-__release_resource-against-resources-without.patch
+++ b/target/linux/brcm2708/patches-4.9/0004-Protect-__release_resource-against-resources-without.patch
@@ -1,4 +1,4 @@
-From 0b4480a51b80954e34605c9bf42947d97e37d1c3 Mon Sep 17 00:00:00 2001
+From 3115fe312a2c751954f1ab0f0ba07aea1c1c7d1b Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 13 Mar 2015 12:43:36 +0000
Subject: [PATCH] Protect __release_resource against resources without parents
diff --git a/target/linux/brcm2708/patches-4.9/0005-mm-Remove-the-PFN-busy-warning.patch b/target/linux/brcm2708/patches-4.9/0005-mm-Remove-the-PFN-busy-warning.patch
index 376d6a8eed..b271d2606d 100644
--- a/target/linux/brcm2708/patches-4.9/0005-mm-Remove-the-PFN-busy-warning.patch
+++ b/target/linux/brcm2708/patches-4.9/0005-mm-Remove-the-PFN-busy-warning.patch
@@ -1,4 +1,4 @@
-From 029f649c29d81583b412cb6ff5792a3cf9102a95 Mon Sep 17 00:00:00 2001
+From 55d0c167f73b9583357fc0af36d7a01666885e0e Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Thu, 18 Dec 2014 16:07:15 -0800
Subject: [PATCH] mm: Remove the PFN busy warning
diff --git a/target/linux/brcm2708/patches-4.9/0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch b/target/linux/brcm2708/patches-4.9/0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch
index 3ebcb0a45f..5f5bd83600 100644
--- a/target/linux/brcm2708/patches-4.9/0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch
+++ b/target/linux/brcm2708/patches-4.9/0006-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch
@@ -1,4 +1,4 @@
-From 3fad09910dafeb93a351aefa90ca4fd490f68c84 Mon Sep 17 00:00:00 2001
+From 0badcb291f4fb5c3477c37b4ad4a0e27dd863272 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 4 Dec 2015 17:41:50 +0000
Subject: [PATCH] irq-bcm2836: Prevent spurious interrupts, and trap them early
diff --git a/target/linux/brcm2708/patches-4.9/0007-irqchip-bcm2835-Add-FIQ-support.patch b/target/linux/brcm2708/patches-4.9/0007-irqchip-bcm2835-Add-FIQ-support.patch
index a25275f073..56be640fd2 100644
--- a/target/linux/brcm2708/patches-4.9/0007-irqchip-bcm2835-Add-FIQ-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0007-irqchip-bcm2835-Add-FIQ-support.patch
@@ -1,4 +1,4 @@
-From 0c9c73fafac86e96a1d1fb59b13aac0ce6d70692 Mon Sep 17 00:00:00 2001
+From 697bdb968798a2bb37c767582ba54fc6486c5de8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 12 Jun 2015 19:01:05 +0200
Subject: [PATCH] irqchip: bcm2835: Add FIQ support
diff --git a/target/linux/brcm2708/patches-4.9/0008-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch b/target/linux/brcm2708/patches-4.9/0008-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch
index 710e73ab00..9c7515f4eb 100644
--- a/target/linux/brcm2708/patches-4.9/0008-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0008-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch
@@ -1,4 +1,4 @@
-From 3b662c4466e336bab7ebb438b65bd5487d30305d Mon Sep 17 00:00:00 2001
+From 78b53021ae0715792fb6a89bd9e7c02fc254be5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 23 Oct 2015 16:26:55 +0200
Subject: [PATCH] irqchip: irq-bcm2835: Add 2836 FIQ support
diff --git a/target/linux/brcm2708/patches-4.9/0010-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch b/target/linux/brcm2708/patches-4.9/0010-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch
index be8e9031cd..447f1ce085 100644
--- a/target/linux/brcm2708/patches-4.9/0010-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch
+++ b/target/linux/brcm2708/patches-4.9/0010-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch
@@ -1,4 +1,4 @@
-From 0059a02a50c6d01a399024cad56ec5254c645fd0 Mon Sep 17 00:00:00 2001
+From cc016c1876877aa42a84cc9c0c89af1b7410ff67 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 30 Jun 2015 14:12:42 +0100
Subject: [PATCH] serial: 8250: Don't crash when nr_uarts is 0
diff --git a/target/linux/brcm2708/patches-4.9/0011-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch b/target/linux/brcm2708/patches-4.9/0011-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch
index 978d675dbf..319eafbb19 100644
--- a/target/linux/brcm2708/patches-4.9/0011-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch
+++ b/target/linux/brcm2708/patches-4.9/0011-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch
@@ -1,4 +1,4 @@
-From c9d0e1314de3cde0674ef5a2c8688b1dc10b2091 Mon Sep 17 00:00:00 2001
+From ea9188a48450ddab740fe5ffe6733fb2362ea5c8 Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Thu, 10 Jul 2014 13:59:47 +0200
Subject: [PATCH] pinctrl-bcm2835: Set base to 0 give expected gpio numbering
diff --git a/target/linux/brcm2708/patches-4.9/0012-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch b/target/linux/brcm2708/patches-4.9/0012-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch
index 67cc420511..b29aa8d7fb 100644
--- a/target/linux/brcm2708/patches-4.9/0012-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch
+++ b/target/linux/brcm2708/patches-4.9/0012-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch
@@ -1,4 +1,4 @@
-From c7ab4eb8e79ceaa923a7c9f4e14dc085a1934a29 Mon Sep 17 00:00:00 2001
+From 6f92d02f7af5a9b5ed5ded7dbeb18bf2bbb2ad85 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 24 Feb 2015 13:40:50 +0000
Subject: [PATCH] pinctrl-bcm2835: Fix interrupt handling for GPIOs 28-31 and
diff --git a/target/linux/brcm2708/patches-4.9/0013-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch b/target/linux/brcm2708/patches-4.9/0013-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch
index e16f89a98e..d2b764f98a 100644
--- a/target/linux/brcm2708/patches-4.9/0013-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch
+++ b/target/linux/brcm2708/patches-4.9/0013-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch
@@ -1,4 +1,4 @@
-From a5a46d240c25576b901f0afa76575c1ab4a1469a Mon Sep 17 00:00:00 2001
+From 6b37913f47f5fbd2748ea9abfb9a17fcfb1b5d29 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 26 Feb 2015 09:58:22 +0000
Subject: [PATCH] pinctrl-bcm2835: Only request the interrupts listed in the
diff --git a/target/linux/brcm2708/patches-4.9/0014-pinctrl-bcm2835-Return-pins-to-inputs-when-freed.patch b/target/linux/brcm2708/patches-4.9/0014-pinctrl-bcm2835-Return-pins-to-inputs-when-freed.patch
index bac0573ba2..4eb4923021 100644
--- a/target/linux/brcm2708/patches-4.9/0014-pinctrl-bcm2835-Return-pins-to-inputs-when-freed.patch
+++ b/target/linux/brcm2708/patches-4.9/0014-pinctrl-bcm2835-Return-pins-to-inputs-when-freed.patch
@@ -1,4 +1,4 @@
-From 403ea1795165839348e5953b80ec4da31b639f8e Mon Sep 17 00:00:00 2001
+From e64023aab5addf920379e9f919d7c5cd4c8d0981 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 6 May 2016 12:32:47 +0100
Subject: [PATCH] pinctrl-bcm2835: Return pins to inputs when freed
diff --git a/target/linux/brcm2708/patches-4.9/0015-spi-bcm2835-Support-pin-groups-other-than-7-11.patch b/target/linux/brcm2708/patches-4.9/0015-spi-bcm2835-Support-pin-groups-other-than-7-11.patch
index 9b8e869ddc..62145a2f07 100644
--- a/target/linux/brcm2708/patches-4.9/0015-spi-bcm2835-Support-pin-groups-other-than-7-11.patch
+++ b/target/linux/brcm2708/patches-4.9/0015-spi-bcm2835-Support-pin-groups-other-than-7-11.patch
@@ -1,4 +1,4 @@
-From d4a8fe93bffd4cab698a2630ee7125da93d55d8a Mon Sep 17 00:00:00 2001
+From 6603973d0897c1a9b3b1a813c8ab1204efe98fe0 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 24 Jun 2015 14:10:44 +0100
Subject: [PATCH] spi-bcm2835: Support pin groups other than 7-11
diff --git a/target/linux/brcm2708/patches-4.9/0016-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/brcm2708/patches-4.9/0016-spi-bcm2835-Disable-forced-software-CS.patch
index 3ec353702c..5d4062c4e4 100644
--- a/target/linux/brcm2708/patches-4.9/0016-spi-bcm2835-Disable-forced-software-CS.patch
+++ b/target/linux/brcm2708/patches-4.9/0016-spi-bcm2835-Disable-forced-software-CS.patch
@@ -1,4 +1,4 @@
-From fa79e1013557f418119bd9dd2c0cf4c51eb4c093 Mon Sep 17 00:00:00 2001
+From c0aaf0d4213bfc9df85c397cd974f7a6f15255f2 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 1 Jul 2016 22:09:24 +0100
Subject: [PATCH] spi-bcm2835: Disable forced software CS
diff --git a/target/linux/brcm2708/patches-4.9/0017-spi-bcm2835-Remove-unused-code.patch b/target/linux/brcm2708/patches-4.9/0017-spi-bcm2835-Remove-unused-code.patch
index 4143498a9d..08577fce2a 100644
--- a/target/linux/brcm2708/patches-4.9/0017-spi-bcm2835-Remove-unused-code.patch
+++ b/target/linux/brcm2708/patches-4.9/0017-spi-bcm2835-Remove-unused-code.patch
@@ -1,4 +1,4 @@
-From 85bb42acd1c5a045d372d187c26b77c6bf1b617a Mon Sep 17 00:00:00 2001
+From 21f7f9d8146dd9e5a860198781febf78aafee3d1 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 8 Nov 2016 21:35:38 +0000
Subject: [PATCH] spi-bcm2835: Remove unused code
diff --git a/target/linux/brcm2708/patches-4.9/0018-ARM-bcm2835-Set-Serial-number-and-Revision.patch b/target/linux/brcm2708/patches-4.9/0018-ARM-bcm2835-Set-Serial-number-and-Revision.patch
index 1311ccb93b..cd14dcc181 100644
--- a/target/linux/brcm2708/patches-4.9/0018-ARM-bcm2835-Set-Serial-number-and-Revision.patch
+++ b/target/linux/brcm2708/patches-4.9/0018-ARM-bcm2835-Set-Serial-number-and-Revision.patch
@@ -1,4 +1,4 @@
-From c33ee72bce07fc83e4797ebea1bce97c0b301ba2 Mon Sep 17 00:00:00 2001
+From 78678f8e9f7fbbafadfecd54a5fb166a94d8d84f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Wed, 3 Jun 2015 12:26:13 +0200
Subject: [PATCH] ARM: bcm2835: Set Serial number and Revision
diff --git a/target/linux/brcm2708/patches-4.9/0019-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch b/target/linux/brcm2708/patches-4.9/0019-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch
index e3bde68d9a..e800713ab8 100644
--- a/target/linux/brcm2708/patches-4.9/0019-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch
+++ b/target/linux/brcm2708/patches-4.9/0019-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch
@@ -1,4 +1,4 @@
-From b4e0c1c3facd38ef5e615248c42dba90d2622257 Mon Sep 17 00:00:00 2001
+From e4f0f7daebca7005c67bf7ae3f6f59df587e91d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Sat, 3 Oct 2015 22:22:55 +0200
Subject: [PATCH] dmaengine: bcm2835: Load driver early and support legacy API
diff --git a/target/linux/brcm2708/patches-4.9/0020-firmware-Updated-mailbox-header.patch b/target/linux/brcm2708/patches-4.9/0020-firmware-Updated-mailbox-header.patch
index deb271c892..37eb154393 100644
--- a/target/linux/brcm2708/patches-4.9/0020-firmware-Updated-mailbox-header.patch
+++ b/target/linux/brcm2708/patches-4.9/0020-firmware-Updated-mailbox-header.patch
@@ -1,4 +1,4 @@
-From 05f9e93200ec5d5e27c8a93f69588180cddda924 Mon Sep 17 00:00:00 2001
+From e4edca57f8db4d03ad4dc82dd6761c0142ab310d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 25 Jan 2016 17:25:12 +0000
Subject: [PATCH] firmware: Updated mailbox header
diff --git a/target/linux/brcm2708/patches-4.9/0021-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch b/target/linux/brcm2708/patches-4.9/0021-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch
index 94862f5bed..dfa312bc37 100644
--- a/target/linux/brcm2708/patches-4.9/0021-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch
+++ b/target/linux/brcm2708/patches-4.9/0021-clk-bcm2835-Mark-GPIO-clocks-enabled-at-boot-as-crit.patch
@@ -1,4 +1,4 @@
-From c9cb54929b3466ed0da304563e22739477055d3b Mon Sep 17 00:00:00 2001
+From 599e7165ec6477139dae4f32a12e8d49d5dd8859 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 9 May 2016 17:28:18 -0700
Subject: [PATCH] clk: bcm2835: Mark GPIO clocks enabled at boot as critical.
diff --git a/target/linux/brcm2708/patches-4.9/0022-rtc-Add-SPI-alias-for-pcf2123-driver.patch b/target/linux/brcm2708/patches-4.9/0022-rtc-Add-SPI-alias-for-pcf2123-driver.patch
index 8c197fce85..4992165a21 100644
--- a/target/linux/brcm2708/patches-4.9/0022-rtc-Add-SPI-alias-for-pcf2123-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0022-rtc-Add-SPI-alias-for-pcf2123-driver.patch
@@ -1,4 +1,4 @@
-From 6c8399fb8dcc815aa9d6b4488a519785912ea983 Mon Sep 17 00:00:00 2001
+From ffa1e97926ba3e22f7e41e2b5e16737461bf31ae Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 15 Jun 2016 16:48:41 +0100
Subject: [PATCH] rtc: Add SPI alias for pcf2123 driver
diff --git a/target/linux/brcm2708/patches-4.9/0023-watchdog-bcm2835-Support-setting-reboot-partition.patch b/target/linux/brcm2708/patches-4.9/0023-watchdog-bcm2835-Support-setting-reboot-partition.patch
index 160c5767f0..392ce70232 100644
--- a/target/linux/brcm2708/patches-4.9/0023-watchdog-bcm2835-Support-setting-reboot-partition.patch
+++ b/target/linux/brcm2708/patches-4.9/0023-watchdog-bcm2835-Support-setting-reboot-partition.patch
@@ -1,4 +1,4 @@
-From 259f169ef05f12bc7fed007befc11ed6c66dd9c8 Mon Sep 17 00:00:00 2001
+From 0e690096e05c3b4e806381ff38124dbdae3ba877 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 7 Oct 2016 16:50:59 +0200
Subject: [PATCH] watchdog: bcm2835: Support setting reboot partition
diff --git a/target/linux/brcm2708/patches-4.9/0024-reboot-Use-power-off-rather-than-busy-spinning-when-.patch b/target/linux/brcm2708/patches-4.9/0024-reboot-Use-power-off-rather-than-busy-spinning-when-.patch
index dee1fed06b..d29517e23f 100644
--- a/target/linux/brcm2708/patches-4.9/0024-reboot-Use-power-off-rather-than-busy-spinning-when-.patch
+++ b/target/linux/brcm2708/patches-4.9/0024-reboot-Use-power-off-rather-than-busy-spinning-when-.patch
@@ -1,4 +1,4 @@
-From 79d93260c98e0164ca89c9f7c767528d7a3aaeae Mon Sep 17 00:00:00 2001
+From 527f4308ee55e8727c486528879b7945b6404a72 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 5 Apr 2016 19:40:12 +0100
Subject: [PATCH] reboot: Use power off rather than busy spinning when halt is
diff --git a/target/linux/brcm2708/patches-4.9/0025-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch b/target/linux/brcm2708/patches-4.9/0025-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch
index 120f25dff5..90c0a0eca8 100644
--- a/target/linux/brcm2708/patches-4.9/0025-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch
+++ b/target/linux/brcm2708/patches-4.9/0025-bcm-Make-RASPBERRYPI_POWER-depend-on-PM.patch
@@ -1,4 +1,4 @@
-From 9799ea4ba8ae1e6c586a3dd728ad75f68830e93f Mon Sep 17 00:00:00 2001
+From d63e8989dc891121464a86cec95952f104edf383 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 9 Nov 2016 13:02:52 +0000
Subject: [PATCH] bcm: Make RASPBERRYPI_POWER depend on PM
diff --git a/target/linux/brcm2708/patches-4.9/0026-Register-the-clocks-early-during-the-boot-process.patch b/target/linux/brcm2708/patches-4.9/0026-Register-the-clocks-early-during-the-boot-process.patch
index d4f4fec92a..9b2a613236 100644
--- a/target/linux/brcm2708/patches-4.9/0026-Register-the-clocks-early-during-the-boot-process.patch
+++ b/target/linux/brcm2708/patches-4.9/0026-Register-the-clocks-early-during-the-boot-process.patch
@@ -1,4 +1,4 @@
-From 261269cc41f6b77f7264f0e44f9b9da5cc36de00 Mon Sep 17 00:00:00 2001
+From 492d6b9c3f1f8cc1eb890dc0eafacae51d6ba2f0 Mon Sep 17 00:00:00 2001
From: Martin Sperl <kernel@martin.sperl.org>
Date: Fri, 2 Sep 2016 16:45:27 +0100
Subject: [PATCH] Register the clocks early during the boot process, so that
diff --git a/target/linux/brcm2708/patches-4.9/0027-bcm2835-rng-Avoid-initialising-if-already-enabled.patch b/target/linux/brcm2708/patches-4.9/0027-bcm2835-rng-Avoid-initialising-if-already-enabled.patch
index 1fb21843ba..97309da0e1 100644
--- a/target/linux/brcm2708/patches-4.9/0027-bcm2835-rng-Avoid-initialising-if-already-enabled.patch
+++ b/target/linux/brcm2708/patches-4.9/0027-bcm2835-rng-Avoid-initialising-if-already-enabled.patch
@@ -1,4 +1,4 @@
-From a195976d635c3672cae684d6338655aa25f6d98c Mon Sep 17 00:00:00 2001
+From ecba31015228961644ad8e17bcf132eea9c7a7f3 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 6 Dec 2016 17:05:39 +0000
Subject: [PATCH] bcm2835-rng: Avoid initialising if already enabled
diff --git a/target/linux/brcm2708/patches-4.9/0028-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch b/target/linux/brcm2708/patches-4.9/0028-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch
index 16d32ccb29..0f5afac4ea 100644
--- a/target/linux/brcm2708/patches-4.9/0028-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch
+++ b/target/linux/brcm2708/patches-4.9/0028-kbuild-Ignore-dtco-targets-when-filtering-symbols.patch
@@ -1,4 +1,4 @@
-From 6c52812a34fa4ab0d40b57fef10d23fe2fb0768b Mon Sep 17 00:00:00 2001
+From d438958d741a4edbb641791461ee8f6c34495a89 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 24 Aug 2016 16:28:44 +0100
Subject: [PATCH] kbuild: Ignore dtco targets when filtering symbols
diff --git a/target/linux/brcm2708/patches-4.9/0029-BCM2835_DT-Fix-I2S-register-map.patch b/target/linux/brcm2708/patches-4.9/0029-BCM2835_DT-Fix-I2S-register-map.patch
index 4eecc143a4..c193ef9167 100644
--- a/target/linux/brcm2708/patches-4.9/0029-BCM2835_DT-Fix-I2S-register-map.patch
+++ b/target/linux/brcm2708/patches-4.9/0029-BCM2835_DT-Fix-I2S-register-map.patch
@@ -1,4 +1,4 @@
-From 8ee6fd93aa3328d325524b8503714e3b4839d1b9 Mon Sep 17 00:00:00 2001
+From 317560a92ebfdac14df54b6a242dd8f5ecc1fd58 Mon Sep 17 00:00:00 2001
From: Robert Tiemann <rtie@gmx.de>
Date: Mon, 20 Jul 2015 11:01:25 +0200
Subject: [PATCH] BCM2835_DT: Fix I2S register map
diff --git a/target/linux/brcm2708/patches-4.9/0030-Main-bcm2708-bcm2709-linux-port.patch b/target/linux/brcm2708/patches-4.9/0030-Main-bcm2708-bcm2709-linux-port.patch
index 81d48b7984..20e5419a74 100644
--- a/target/linux/brcm2708/patches-4.9/0030-Main-bcm2708-bcm2709-linux-port.patch
+++ b/target/linux/brcm2708/patches-4.9/0030-Main-bcm2708-bcm2709-linux-port.patch
@@ -1,4 +1,4 @@
-From 28a1aeb6b49ffdf5cb5ba9e326df962c270c1f34 Mon Sep 17 00:00:00 2001
+From 9874eb6473865b9d975a7c3756099955e7454e21 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Sun, 12 May 2013 12:24:19 +0100
Subject: [PATCH] Main bcm2708/bcm2709 linux port
diff --git a/target/linux/brcm2708/patches-4.9/0031-Add-dwc_otg-driver.patch b/target/linux/brcm2708/patches-4.9/0031-Add-dwc_otg-driver.patch
index 971581ad0b..0610d038b6 100644
--- a/target/linux/brcm2708/patches-4.9/0031-Add-dwc_otg-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0031-Add-dwc_otg-driver.patch
@@ -1,4 +1,4 @@
-From 4c7d2ae77def863967cbc6e73597d92fe0fb24e7 Mon Sep 17 00:00:00 2001
+From 65f57e56fcf9d40383718f0bcd9e6f95a34ca1aa Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 1 May 2013 19:46:17 +0100
Subject: [PATCH] Add dwc_otg driver
diff --git a/target/linux/brcm2708/patches-4.9/0032-bcm2708-framebuffer-driver.patch b/target/linux/brcm2708/patches-4.9/0032-bcm2708-framebuffer-driver.patch
index a306868728..b7c05c1611 100644
--- a/target/linux/brcm2708/patches-4.9/0032-bcm2708-framebuffer-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0032-bcm2708-framebuffer-driver.patch
@@ -1,4 +1,4 @@
-From a5db9164cfc4fdbd25b20962f3da042cdc75a4dc Mon Sep 17 00:00:00 2001
+From cca69d888eb770c496cca83d37accb62a22e84c7 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 17:06:34 +0100
Subject: [PATCH] bcm2708 framebuffer driver
diff --git a/target/linux/brcm2708/patches-4.9/0033-dmaengine-Add-support-for-BCM2708.patch b/target/linux/brcm2708/patches-4.9/0033-dmaengine-Add-support-for-BCM2708.patch
index d21f18777a..a2f45519b6 100644
--- a/target/linux/brcm2708/patches-4.9/0033-dmaengine-Add-support-for-BCM2708.patch
+++ b/target/linux/brcm2708/patches-4.9/0033-dmaengine-Add-support-for-BCM2708.patch
@@ -1,4 +1,4 @@
-From 5ab35842ff7cc211dcfbf1113953778923097496 Mon Sep 17 00:00:00 2001
+From 33444cee555204ee605e6ec9050b04e874fb0090 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 14:22:53 +0100
Subject: [PATCH] dmaengine: Add support for BCM2708
diff --git a/target/linux/brcm2708/patches-4.9/0034-MMC-added-alternative-MMC-driver.patch b/target/linux/brcm2708/patches-4.9/0034-MMC-added-alternative-MMC-driver.patch
index 00920a6223..70fb8f3d8c 100644
--- a/target/linux/brcm2708/patches-4.9/0034-MMC-added-alternative-MMC-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0034-MMC-added-alternative-MMC-driver.patch
@@ -1,4 +1,4 @@
-From feab5b6b38842fca38720e0b2e9bfdc66d41c991 Mon Sep 17 00:00:00 2001
+From 1620619c5fa6acae1e119d6461b5c9a2a9416e69 Mon Sep 17 00:00:00 2001
From: gellert <gellert@raspberrypi.org>
Date: Fri, 15 Aug 2014 16:35:06 +0100
Subject: [PATCH] MMC: added alternative MMC driver
diff --git a/target/linux/brcm2708/patches-4.9/0035-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch b/target/linux/brcm2708/patches-4.9/0035-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch
index c6ceef081a..c4597ec3c1 100644
--- a/target/linux/brcm2708/patches-4.9/0035-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch
+++ b/target/linux/brcm2708/patches-4.9/0035-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch
@@ -1,4 +1,4 @@
-From 3d0f0b3db1b62e5d913517ce305913cc71803ef1 Mon Sep 17 00:00:00 2001
+From 5da331581bb2a8d90f6a7a7bdf8c1b30efe3cf64 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 25 Mar 2015 17:49:47 +0000
Subject: [PATCH] Adding bcm2835-sdhost driver, and an overlay to enable it
diff --git a/target/linux/brcm2708/patches-4.9/0036-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch b/target/linux/brcm2708/patches-4.9/0036-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch
index 100c8b1685..d84a0fe892 100644
--- a/target/linux/brcm2708/patches-4.9/0036-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch
+++ b/target/linux/brcm2708/patches-4.9/0036-mmc-Add-MMC_QUIRK_ERASE_BROKEN-for-some-cards.patch
@@ -1,4 +1,4 @@
-From f6be5bc28ee258731e13b5e917d69f601d062014 Mon Sep 17 00:00:00 2001
+From 6d11059a087b8101cf34a09a1e3342bb4f1576de Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 11 May 2016 12:50:33 +0100
Subject: [PATCH] mmc: Add MMC_QUIRK_ERASE_BROKEN for some cards
diff --git a/target/linux/brcm2708/patches-4.9/0037-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch b/target/linux/brcm2708/patches-4.9/0037-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch
index 87b62dcf8f..50bad76c51 100644
--- a/target/linux/brcm2708/patches-4.9/0037-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch
+++ b/target/linux/brcm2708/patches-4.9/0037-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch
@@ -1,4 +1,4 @@
-From a079bbcd1d23f00392eb79d7bcad867844f84cd9 Mon Sep 17 00:00:00 2001
+From 4d96064d4c95d73d22563cea403eccd72e7b0da0 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:31:47 +0100
Subject: [PATCH] cma: Add vc_cma driver to enable use of CMA
diff --git a/target/linux/brcm2708/patches-4.9/0038-bcm2708-alsa-sound-driver.patch b/target/linux/brcm2708/patches-4.9/0038-bcm2708-alsa-sound-driver.patch
index c951b6f52c..58b45dec6e 100644
--- a/target/linux/brcm2708/patches-4.9/0038-bcm2708-alsa-sound-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0038-bcm2708-alsa-sound-driver.patch
@@ -1,4 +1,4 @@
-From 340dfdd9f8dfad3f60665cac7f19d774c001b0de Mon Sep 17 00:00:00 2001
+From 41a90e24c272c84fb8c6d23ac451f0c725dcded6 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 26 Mar 2012 22:15:50 +0100
Subject: [PATCH] bcm2708: alsa sound driver
diff --git a/target/linux/brcm2708/patches-4.9/0039-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch b/target/linux/brcm2708/patches-4.9/0039-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch
index fbfddde33a..6a22bdf970 100644
--- a/target/linux/brcm2708/patches-4.9/0039-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch
+++ b/target/linux/brcm2708/patches-4.9/0039-vc_mem-Add-vc_mem-driver-for-querying-firmware-memor.patch
@@ -1,4 +1,4 @@
-From 079c7a4a324b1baa4e727c9e3dfacf503345bb18 Mon Sep 17 00:00:00 2001
+From 94c0e75bc85ad2a034c501b6d3640b880b9c3bb7 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Fri, 28 Oct 2016 15:36:43 +0100
Subject: [PATCH] vc_mem: Add vc_mem driver for querying firmware memory
diff --git a/target/linux/brcm2708/patches-4.9/0040-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch b/target/linux/brcm2708/patches-4.9/0040-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch
index d7bce81d59..ff1cfad30a 100644
--- a/target/linux/brcm2708/patches-4.9/0040-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch
+++ b/target/linux/brcm2708/patches-4.9/0040-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch
@@ -1,4 +1,4 @@
-From 148da7d48af0416c716b0103bcc14d01cc97d09b Mon Sep 17 00:00:00 2001
+From b62c07606f1673e2e0b9e70ce89e48fc240a7ee1 Mon Sep 17 00:00:00 2001
From: Tim Gover <tgover@broadcom.com>
Date: Tue, 22 Jul 2014 15:41:04 +0100
Subject: [PATCH] vcsm: VideoCore shared memory service for BCM2835
diff --git a/target/linux/brcm2708/patches-4.9/0041-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch b/target/linux/brcm2708/patches-4.9/0041-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch
index 66949f5e9b..618cb9f8dd 100644
--- a/target/linux/brcm2708/patches-4.9/0041-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch
+++ b/target/linux/brcm2708/patches-4.9/0041-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch
@@ -1,4 +1,4 @@
-From f035c5328fecc8970b9a9713cd345d56f5e81f98 Mon Sep 17 00:00:00 2001
+From 0f326aa0cf8a16ab7f29606b2eda7186f1fb9367 Mon Sep 17 00:00:00 2001
From: Luke Wren <luke@raspberrypi.org>
Date: Fri, 21 Aug 2015 23:14:48 +0100
Subject: [PATCH] Add /dev/gpiomem device for rootless user GPIO access
diff --git a/target/linux/brcm2708/patches-4.9/0042-Add-SMI-driver.patch b/target/linux/brcm2708/patches-4.9/0042-Add-SMI-driver.patch
index 7a05db457b..3d75e705ba 100644
--- a/target/linux/brcm2708/patches-4.9/0042-Add-SMI-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0042-Add-SMI-driver.patch
@@ -1,4 +1,4 @@
-From ddedd1f135c5311bb4615dda5b285ce688cc50d4 Mon Sep 17 00:00:00 2001
+From 8b3f935c48ff65dfb8985ce3e6c631530cd1471a Mon Sep 17 00:00:00 2001
From: Luke Wren <wren6991@gmail.com>
Date: Sat, 5 Sep 2015 01:14:45 +0100
Subject: [PATCH] Add SMI driver
diff --git a/target/linux/brcm2708/patches-4.9/0043-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch b/target/linux/brcm2708/patches-4.9/0043-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch
index 312a294bc7..69f68c79ed 100644
--- a/target/linux/brcm2708/patches-4.9/0043-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch
+++ b/target/linux/brcm2708/patches-4.9/0043-MISC-bcm2835-smi-use-clock-manager-and-fix-reload-is.patch
@@ -1,4 +1,4 @@
-From 6e5058f6cb203dd31935ba03eeff0d98c7531bcf Mon Sep 17 00:00:00 2001
+From 6bc6d433aaed4d4a5d5be44e70d9de865a850048 Mon Sep 17 00:00:00 2001
From: Martin Sperl <kernel@martin.sperl.org>
Date: Tue, 26 Apr 2016 14:59:21 +0000
Subject: [PATCH] MISC: bcm2835: smi: use clock manager and fix reload issues
diff --git a/target/linux/brcm2708/patches-4.9/0044-Add-SMI-NAND-driver.patch b/target/linux/brcm2708/patches-4.9/0044-Add-SMI-NAND-driver.patch
index dee3c1d8b0..ec6010a296 100644
--- a/target/linux/brcm2708/patches-4.9/0044-Add-SMI-NAND-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0044-Add-SMI-NAND-driver.patch
@@ -1,4 +1,4 @@
-From 83148030b231764e7a5fc14bd2c9ccc6a104a872 Mon Sep 17 00:00:00 2001
+From be64c4dbf6be17ce20ee214478509a3738256d46 Mon Sep 17 00:00:00 2001
From: Luke Wren <wren6991@gmail.com>
Date: Sat, 5 Sep 2015 01:16:10 +0100
Subject: [PATCH] Add SMI NAND driver
diff --git a/target/linux/brcm2708/patches-4.9/0045-lirc-added-support-for-RaspberryPi-GPIO.patch b/target/linux/brcm2708/patches-4.9/0045-lirc-added-support-for-RaspberryPi-GPIO.patch
index ea529b89a0..0cbc1c45a4 100644
--- a/target/linux/brcm2708/patches-4.9/0045-lirc-added-support-for-RaspberryPi-GPIO.patch
+++ b/target/linux/brcm2708/patches-4.9/0045-lirc-added-support-for-RaspberryPi-GPIO.patch
@@ -1,4 +1,4 @@
-From e12517458be7d5ec0eccc2c23db2b78badd54587 Mon Sep 17 00:00:00 2001
+From 277c109833c1d78543bec0723ab42f4c79937df9 Mon Sep 17 00:00:00 2001
From: Aron Szabo <aron@aron.ws>
Date: Sat, 16 Jun 2012 12:15:55 +0200
Subject: [PATCH] lirc: added support for RaspberryPi GPIO
diff --git a/target/linux/brcm2708/patches-4.9/0046-Add-cpufreq-driver.patch b/target/linux/brcm2708/patches-4.9/0046-Add-cpufreq-driver.patch
index 8929ee23ab..7c5691c120 100644
--- a/target/linux/brcm2708/patches-4.9/0046-Add-cpufreq-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0046-Add-cpufreq-driver.patch
@@ -1,4 +1,4 @@
-From 91eeb6693671b5ae0220f4a276b84e6597266cb9 Mon Sep 17 00:00:00 2001
+From 7d4719c360b755637c2e68f9855be282cd0065b6 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:49:20 +0100
Subject: [PATCH] Add cpufreq driver
diff --git a/target/linux/brcm2708/patches-4.9/0047-Added-hwmon-thermal-driver-for-reporting-core-temper.patch b/target/linux/brcm2708/patches-4.9/0047-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
index fa826cbaf4..ff6084fe6a 100644
--- a/target/linux/brcm2708/patches-4.9/0047-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
+++ b/target/linux/brcm2708/patches-4.9/0047-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
@@ -1,4 +1,4 @@
-From c83d1bbc2d9feaf23252482682824babbbd7bbd9 Mon Sep 17 00:00:00 2001
+From 3c847bc6c9d6f4115c82943c869c55244b39a5c4 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 26 Mar 2013 19:24:24 +0000
Subject: [PATCH] Added hwmon/thermal driver for reporting core temperature.
diff --git a/target/linux/brcm2708/patches-4.9/0048-Add-Chris-Boot-s-i2c-driver.patch b/target/linux/brcm2708/patches-4.9/0048-Add-Chris-Boot-s-i2c-driver.patch
index acb199d848..b86fb40b62 100644
--- a/target/linux/brcm2708/patches-4.9/0048-Add-Chris-Boot-s-i2c-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0048-Add-Chris-Boot-s-i2c-driver.patch
@@ -1,4 +1,4 @@
-From d34838cfa7c139fa069b7e038d3ea2b56c50a353 Mon Sep 17 00:00:00 2001
+From af4e8a3c7b645480f57ec14ded02fba6976ff2d5 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 17 Jun 2015 15:44:08 +0100
Subject: [PATCH] Add Chris Boot's i2c driver
diff --git a/target/linux/brcm2708/patches-4.9/0049-char-broadcom-Add-vcio-module.patch b/target/linux/brcm2708/patches-4.9/0049-char-broadcom-Add-vcio-module.patch
index cd62abe4d1..c37c0f6133 100644
--- a/target/linux/brcm2708/patches-4.9/0049-char-broadcom-Add-vcio-module.patch
+++ b/target/linux/brcm2708/patches-4.9/0049-char-broadcom-Add-vcio-module.patch
@@ -1,4 +1,4 @@
-From e826eaf145a568f477ab9e5554a563233ad7fb49 Mon Sep 17 00:00:00 2001
+From 2e8101a5e6228109d2cd5b965b6077e63e643d6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:27:06 +0200
Subject: [PATCH] char: broadcom: Add vcio module
diff --git a/target/linux/brcm2708/patches-4.9/0050-firmware-bcm2835-Support-ARCH_BCM270x.patch b/target/linux/brcm2708/patches-4.9/0050-firmware-bcm2835-Support-ARCH_BCM270x.patch
index 3e47d68ef4..ecaf614c16 100644
--- a/target/linux/brcm2708/patches-4.9/0050-firmware-bcm2835-Support-ARCH_BCM270x.patch
+++ b/target/linux/brcm2708/patches-4.9/0050-firmware-bcm2835-Support-ARCH_BCM270x.patch
@@ -1,4 +1,4 @@
-From 2838aca7eb2ef14cb94ac43921fc2db291af96a7 Mon Sep 17 00:00:00 2001
+From f281fd683848cd432f7b73c869676be6362ce1b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 26 Jun 2015 14:25:01 +0200
Subject: [PATCH] firmware: bcm2835: Support ARCH_BCM270x
diff --git a/target/linux/brcm2708/patches-4.9/0051-bcm2835-add-v4l2-camera-device.patch b/target/linux/brcm2708/patches-4.9/0051-bcm2835-add-v4l2-camera-device.patch
index 2e77160a85..e6baeabfd3 100644
--- a/target/linux/brcm2708/patches-4.9/0051-bcm2835-add-v4l2-camera-device.patch
+++ b/target/linux/brcm2708/patches-4.9/0051-bcm2835-add-v4l2-camera-device.patch
@@ -1,4 +1,4 @@
-From 35fa034f52f341a95e10034b2f36e2af05fee117 Mon Sep 17 00:00:00 2001
+From 88f7fe5348a24191969b07537b38449a83369d32 Mon Sep 17 00:00:00 2001
From: Vincent Sanders <vincent.sanders@collabora.co.uk>
Date: Wed, 30 Jan 2013 12:45:18 +0000
Subject: [PATCH] bcm2835: add v4l2 camera device
diff --git a/target/linux/brcm2708/patches-4.9/0052-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch b/target/linux/brcm2708/patches-4.9/0052-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch
index 6feda0ee07..7ae4edd5c2 100644
--- a/target/linux/brcm2708/patches-4.9/0052-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch
+++ b/target/linux/brcm2708/patches-4.9/0052-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch
@@ -1,4 +1,4 @@
-From 59799351c2a2951565e10b2ef69ccff34f94fd30 Mon Sep 17 00:00:00 2001
+From c1275c733d61290f7477eb7bbaea96d04206eff3 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 11 May 2015 09:00:42 +0100
Subject: [PATCH] scripts: Add mkknlimg and knlinfo scripts from tools repo
diff --git a/target/linux/brcm2708/patches-4.9/0053-scripts-dtc-Update-to-upstream-version-1.4.1.patch b/target/linux/brcm2708/patches-4.9/0053-scripts-dtc-Update-to-upstream-version-1.4.1.patch
index 5fdf0241d3..ed4b27092b 100644
--- a/target/linux/brcm2708/patches-4.9/0053-scripts-dtc-Update-to-upstream-version-1.4.1.patch
+++ b/target/linux/brcm2708/patches-4.9/0053-scripts-dtc-Update-to-upstream-version-1.4.1.patch
@@ -1,4 +1,4 @@
-From 913a79481bedcfed6727e899ab3f5a9291328f55 Mon Sep 17 00:00:00 2001
+From 61ad4b70c72fd7d1d3930b50e180d9727eeae150 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 10 Aug 2015 09:49:15 +0100
Subject: [PATCH] scripts/dtc: Update to upstream version 1.4.1
diff --git a/target/linux/brcm2708/patches-4.9/0054-BCM2708-Add-core-Device-Tree-support.patch b/target/linux/brcm2708/patches-4.9/0054-BCM2708-Add-core-Device-Tree-support.patch
index 6767122451..d9d1fa9a58 100644
--- a/target/linux/brcm2708/patches-4.9/0054-BCM2708-Add-core-Device-Tree-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0054-BCM2708-Add-core-Device-Tree-support.patch
@@ -1,4 +1,4 @@
-From 2ad7caa56296821bfab4ce0e808a0d1d2c8ac9f4 Mon Sep 17 00:00:00 2001
+From 589cd87acedc0e24214934816b6c16b4e76a894d Mon Sep 17 00:00:00 2001
From: notro <notro@tronnes.org>
Date: Wed, 9 Jul 2014 14:46:08 +0200
Subject: [PATCH] BCM2708: Add core Device Tree support
diff --git a/target/linux/brcm2708/patches-4.9/0055-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch b/target/linux/brcm2708/patches-4.9/0055-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch
index 50a0ed7a1e..725ac70e44 100644
--- a/target/linux/brcm2708/patches-4.9/0055-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch
+++ b/target/linux/brcm2708/patches-4.9/0055-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch
@@ -1,4 +1,4 @@
-From f760337032ce3078b0ecfe2ec8420bbdf173151d Mon Sep 17 00:00:00 2001
+From 766357a4f8476461035dcfe2c6b43f532366f533 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 6 Feb 2015 13:50:57 +0000
Subject: [PATCH] BCM270x_DT: Add pwr_led, and the required "input" trigger
diff --git a/target/linux/brcm2708/patches-4.9/0056-fbdev-add-FBIOCOPYAREA-ioctl.patch b/target/linux/brcm2708/patches-4.9/0056-fbdev-add-FBIOCOPYAREA-ioctl.patch
index 44414e5481..34346903da 100644
--- a/target/linux/brcm2708/patches-4.9/0056-fbdev-add-FBIOCOPYAREA-ioctl.patch
+++ b/target/linux/brcm2708/patches-4.9/0056-fbdev-add-FBIOCOPYAREA-ioctl.patch
@@ -1,4 +1,4 @@
-From c19ea76c6206a3e5a897cef2da65d82c6dd76430 Mon Sep 17 00:00:00 2001
+From 65422160b21224e6d26641a4c1fa3082c0281488 Mon Sep 17 00:00:00 2001
From: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Date: Mon, 17 Jun 2013 13:32:11 +0300
Subject: [PATCH] fbdev: add FBIOCOPYAREA ioctl
diff --git a/target/linux/brcm2708/patches-4.9/0057-Speed-up-console-framebuffer-imageblit-function.patch b/target/linux/brcm2708/patches-4.9/0057-Speed-up-console-framebuffer-imageblit-function.patch
index f0e7392e64..8d6337a94d 100644
--- a/target/linux/brcm2708/patches-4.9/0057-Speed-up-console-framebuffer-imageblit-function.patch
+++ b/target/linux/brcm2708/patches-4.9/0057-Speed-up-console-framebuffer-imageblit-function.patch
@@ -1,4 +1,4 @@
-From 11db806d75a8958fb706d8a1b4e67818a04d68c7 Mon Sep 17 00:00:00 2001
+From fead9bc9e55df547b54a9cd55d932b209090cfeb Mon Sep 17 00:00:00 2001
From: Harm Hanemaaijer <fgenfb@yahoo.com>
Date: Thu, 20 Jun 2013 20:21:39 +0200
Subject: [PATCH] Speed up console framebuffer imageblit function
diff --git a/target/linux/brcm2708/patches-4.9/0058-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch b/target/linux/brcm2708/patches-4.9/0058-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
index 5c3e0641cb..408ac045f7 100644
--- a/target/linux/brcm2708/patches-4.9/0058-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
+++ b/target/linux/brcm2708/patches-4.9/0058-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
@@ -1,4 +1,4 @@
-From d387edf492067aa0d298b90829b784f640375e7c Mon Sep 17 00:00:00 2001
+From 5edc95eee5ef69d7bfe03eede0e711e8f196dedc Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 8 May 2013 11:46:50 +0100
Subject: [PATCH] enabling the realtime clock 1-wire chip DS1307 and 1-wire on
diff --git a/target/linux/brcm2708/patches-4.9/0059-Added-Device-IDs-for-August-DVB-T-205.patch b/target/linux/brcm2708/patches-4.9/0059-Added-Device-IDs-for-August-DVB-T-205.patch
index ec376d40f2..a9906f3e3c 100644
--- a/target/linux/brcm2708/patches-4.9/0059-Added-Device-IDs-for-August-DVB-T-205.patch
+++ b/target/linux/brcm2708/patches-4.9/0059-Added-Device-IDs-for-August-DVB-T-205.patch
@@ -1,4 +1,4 @@
-From c7850d63ac4cf12c0a70c2014cc2451a5118e717 Mon Sep 17 00:00:00 2001
+From 0d3a6a7484390def36773cb4fee0e16d6b8c45d1 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 3 Jul 2013 00:54:08 +0100
Subject: [PATCH] Added Device IDs for August DVB-T 205
diff --git a/target/linux/brcm2708/patches-4.9/0060-config-Enable-CONFIG_MEMCG-but-leave-it-disabled-due.patch b/target/linux/brcm2708/patches-4.9/0060-config-Enable-CONFIG_MEMCG-but-leave-it-disabled-due.patch
index a2eca8a994..73c9edeea4 100644
--- a/target/linux/brcm2708/patches-4.9/0060-config-Enable-CONFIG_MEMCG-but-leave-it-disabled-due.patch
+++ b/target/linux/brcm2708/patches-4.9/0060-config-Enable-CONFIG_MEMCG-but-leave-it-disabled-due.patch
@@ -1,4 +1,4 @@
-From d8fe940fffef38e498beaa5bd182647452d98de9 Mon Sep 17 00:00:00 2001
+From c50fe09c78e9b87137e0188139c774bd4f12dcb2 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 18 Dec 2013 22:16:19 +0000
Subject: [PATCH] config: Enable CONFIG_MEMCG, but leave it disabled (due to
diff --git a/target/linux/brcm2708/patches-4.9/0061-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch b/target/linux/brcm2708/patches-4.9/0061-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch
index e9f34194c7..444c64e471 100644
--- a/target/linux/brcm2708/patches-4.9/0061-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch
+++ b/target/linux/brcm2708/patches-4.9/0061-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch
@@ -1,4 +1,4 @@
-From 1697df63a0dd1cdc54f304cfb7c4a3a997661f06 Mon Sep 17 00:00:00 2001
+From 56f13ae9d518c5aec8736ccc639f2f5e2c3784ad Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 14 Jul 2014 22:02:09 +0100
Subject: [PATCH] hid: Reduce default mouse polling interval to 60Hz
diff --git a/target/linux/brcm2708/patches-4.9/0062-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch b/target/linux/brcm2708/patches-4.9/0062-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch
index 3d98c22570..43ed3faa9c 100644
--- a/target/linux/brcm2708/patches-4.9/0062-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch
+++ b/target/linux/brcm2708/patches-4.9/0062-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch
@@ -1,4 +1,4 @@
-From e7fa4e5d3db9996074a22db9eff4833d33d11fb6 Mon Sep 17 00:00:00 2001
+From 18c740925ca44b8a2f55ac201acf935f9fa97515 Mon Sep 17 00:00:00 2001
From: Gordon Hollingworth <gordon@raspberrypi.org>
Date: Tue, 12 May 2015 14:47:56 +0100
Subject: [PATCH] rpi-ft5406: Add touchscreen driver for pi LCD display
diff --git a/target/linux/brcm2708/patches-4.9/0063-Improve-__copy_to_user-and-__copy_from_user-performa.patch b/target/linux/brcm2708/patches-4.9/0063-Improve-__copy_to_user-and-__copy_from_user-performa.patch
index 2d92f77a6f..a7ce64ba38 100644
--- a/target/linux/brcm2708/patches-4.9/0063-Improve-__copy_to_user-and-__copy_from_user-performa.patch
+++ b/target/linux/brcm2708/patches-4.9/0063-Improve-__copy_to_user-and-__copy_from_user-performa.patch
@@ -1,4 +1,4 @@
-From 77346574b6cd6bfbeac98ac6c711c281a71adebb Mon Sep 17 00:00:00 2001
+From ebd731dd71ec9728a5a87ec1cd695be15828c32c Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 28 Nov 2016 16:50:04 +0000
Subject: [PATCH] Improve __copy_to_user and __copy_from_user performance
diff --git a/target/linux/brcm2708/patches-4.9/0064-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch b/target/linux/brcm2708/patches-4.9/0064-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch
index 3a86d97108..5d73a28246 100644
--- a/target/linux/brcm2708/patches-4.9/0064-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch
+++ b/target/linux/brcm2708/patches-4.9/0064-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch
@@ -1,4 +1,4 @@
-From da2b72916e1fa0824a139bda7f28216640d6727c Mon Sep 17 00:00:00 2001
+From 7e8bb86739df17e38a0ebe6e17b7a9056ab421e9 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 25 Jun 2015 12:16:11 +0100
Subject: [PATCH] gpio-poweroff: Allow it to work on Raspberry Pi
diff --git a/target/linux/brcm2708/patches-4.9/0065-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch b/target/linux/brcm2708/patches-4.9/0065-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch
index 77079e0493..b5ae3f954c 100644
--- a/target/linux/brcm2708/patches-4.9/0065-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0065-mfd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch
@@ -1,4 +1,4 @@
-From 91d2e7c60d71cd4450ee3ac68b8fcdfe7f93a1f0 Mon Sep 17 00:00:00 2001
+From 157f59328885549a0f2c1fe35e9ec3aff0f0b52e Mon Sep 17 00:00:00 2001
From: Phil Elwell <pelwell@users.noreply.github.com>
Date: Tue, 14 Jul 2015 14:32:47 +0100
Subject: [PATCH] mfd: Add Raspberry Pi Sense HAT core driver
diff --git a/target/linux/brcm2708/patches-4.9/0066-ASoC-Add-support-for-HifiBerry-DAC.patch b/target/linux/brcm2708/patches-4.9/0066-ASoC-Add-support-for-HifiBerry-DAC.patch
index 22f8654d68..107ed28c1b 100644
--- a/target/linux/brcm2708/patches-4.9/0066-ASoC-Add-support-for-HifiBerry-DAC.patch
+++ b/target/linux/brcm2708/patches-4.9/0066-ASoC-Add-support-for-HifiBerry-DAC.patch
@@ -1,4 +1,4 @@
-From c9f07d6d39019ae80e97e0d1cf070a78c4a6c974 Mon Sep 17 00:00:00 2001
+From fe9fdf49ba81e28860e5367ea8bb9c6b1c6a0460 Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Fri, 22 Nov 2013 19:19:08 +0100
Subject: [PATCH] ASoC: Add support for HifiBerry DAC
diff --git a/target/linux/brcm2708/patches-4.9/0067-ASoC-Add-support-for-Rpi-DAC.patch b/target/linux/brcm2708/patches-4.9/0067-ASoC-Add-support-for-Rpi-DAC.patch
index 0353820121..26ae5b3d76 100644
--- a/target/linux/brcm2708/patches-4.9/0067-ASoC-Add-support-for-Rpi-DAC.patch
+++ b/target/linux/brcm2708/patches-4.9/0067-ASoC-Add-support-for-Rpi-DAC.patch
@@ -1,4 +1,4 @@
-From fd63dade0da2751e1b4d38a7bc1f70611bf85e31 Mon Sep 17 00:00:00 2001
+From 3a890b43d08fbfe10895f733578f095a6449ba0b Mon Sep 17 00:00:00 2001
From: Florian Meier <florian.meier@koalo.de>
Date: Mon, 25 Jan 2016 15:48:59 +0000
Subject: [PATCH] ASoC: Add support for Rpi-DAC
diff --git a/target/linux/brcm2708/patches-4.9/0068-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch b/target/linux/brcm2708/patches-4.9/0068-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch
index 7accb99842..1be734befa 100644
--- a/target/linux/brcm2708/patches-4.9/0068-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch
+++ b/target/linux/brcm2708/patches-4.9/0068-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch
@@ -1,4 +1,4 @@
-From c137d8fd4fd6a01ca8afc140cab7d7c3c39f3f33 Mon Sep 17 00:00:00 2001
+From 8432dc7c8a843e7c35d7624adc6653e13dd488a7 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Wed, 15 Jan 2014 21:41:23 +0100
Subject: [PATCH] ASoC: wm8804: Implement MCLK configuration options, add 32bit
diff --git a/target/linux/brcm2708/patches-4.9/0069-ASoC-BCM-Add-support-for-HiFiBerry-Digi.-Driver-is-b.patch b/target/linux/brcm2708/patches-4.9/0069-ASoC-BCM-Add-support-for-HiFiBerry-Digi.-Driver-is-b.patch
index d9dc426649..5f8477cd7b 100644
--- a/target/linux/brcm2708/patches-4.9/0069-ASoC-BCM-Add-support-for-HiFiBerry-Digi.-Driver-is-b.patch
+++ b/target/linux/brcm2708/patches-4.9/0069-ASoC-BCM-Add-support-for-HiFiBerry-Digi.-Driver-is-b.patch
@@ -1,4 +1,4 @@
-From 8a6178b707acd262871cb08791f8d9e7248a4107 Mon Sep 17 00:00:00 2001
+From ded3c4c0c46af840159e4fc79a065d69cbb7b534 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Wed, 15 Jan 2014 21:42:08 +0100
Subject: [PATCH] ASoC: BCM:Add support for HiFiBerry Digi. Driver is based on
diff --git a/target/linux/brcm2708/patches-4.9/0070-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch b/target/linux/brcm2708/patches-4.9/0070-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch
index 483fc6e791..08bf856c9f 100644
--- a/target/linux/brcm2708/patches-4.9/0070-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch
+++ b/target/linux/brcm2708/patches-4.9/0070-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch
@@ -1,4 +1,4 @@
-From db63efa8452156b71aedb5aa1e77182d25bc6906 Mon Sep 17 00:00:00 2001
+From fcfe9087b79176b5d8afd0ecc4c66013866ef239 Mon Sep 17 00:00:00 2001
From: Gordon Garrity <gordon@iqaudio.com>
Date: Sat, 8 Mar 2014 16:56:57 +0000
Subject: [PATCH] Add IQaudIO Sound Card support for Raspberry Pi
diff --git a/target/linux/brcm2708/patches-4.9/0071-iqaudio-dac-Compile-fix-untested.patch b/target/linux/brcm2708/patches-4.9/0071-iqaudio-dac-Compile-fix-untested.patch
index 51d731aded..edfb9f5e1f 100644
--- a/target/linux/brcm2708/patches-4.9/0071-iqaudio-dac-Compile-fix-untested.patch
+++ b/target/linux/brcm2708/patches-4.9/0071-iqaudio-dac-Compile-fix-untested.patch
@@ -1,4 +1,4 @@
-From bde9a1a68dbc0fe50a899b2178128068482f4ec9 Mon Sep 17 00:00:00 2001
+From 711f7413d72af6328a3958eecd400bd8911af211 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 25 Jul 2016 17:06:50 +0100
Subject: [PATCH] iqaudio-dac: Compile fix - untested
diff --git a/target/linux/brcm2708/patches-4.9/0072-Added-support-for-HiFiBerry-DAC.patch b/target/linux/brcm2708/patches-4.9/0072-Added-support-for-HiFiBerry-DAC.patch
index daccc7c144..21d30af475 100644
--- a/target/linux/brcm2708/patches-4.9/0072-Added-support-for-HiFiBerry-DAC.patch
+++ b/target/linux/brcm2708/patches-4.9/0072-Added-support-for-HiFiBerry-DAC.patch
@@ -1,4 +1,4 @@
-From 728a454670c1c65e518a81122683f6cd1e08e967 Mon Sep 17 00:00:00 2001
+From 9c6b8bd0db7564a2124290e3bc30215906371fa9 Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Mon, 4 Aug 2014 10:06:56 +0200
Subject: [PATCH] Added support for HiFiBerry DAC+
diff --git a/target/linux/brcm2708/patches-4.9/0073-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch b/target/linux/brcm2708/patches-4.9/0073-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch
index fb823d2e7c..9826be5725 100644
--- a/target/linux/brcm2708/patches-4.9/0073-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch
+++ b/target/linux/brcm2708/patches-4.9/0073-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch
@@ -1,4 +1,4 @@
-From a9a8a1127418a342cfd7409d10137cbe4e20b951 Mon Sep 17 00:00:00 2001
+From 0f11b0757d5950ee7a8ba00e49ebefd2c649a6ba Mon Sep 17 00:00:00 2001
From: Daniel Matuschek <info@crazy-audio.com>
Date: Mon, 4 Aug 2014 11:09:58 +0200
Subject: [PATCH] Added driver for HiFiBerry Amp amplifier add-on board
@@ -16,15 +16,19 @@ reported correctly by a non-zero return code.
HiFiBerry Amp: fix device-tree problems
Some code to load the driver based on device-tree-overlays was missing. This is added by this patch.
+
+hifiberry-amp: Adjust for ALSA object refactoring
+
+See: https://github.com/raspberrypi/linux/issues/1775
---
sound/soc/bcm/Kconfig | 7 +
sound/soc/bcm/Makefile | 2 +
sound/soc/bcm/hifiberry_amp.c | 129 +++++++++++++++
sound/soc/codecs/Kconfig | 4 +
sound/soc/codecs/Makefile | 2 +
- sound/soc/codecs/tas5713.c | 369 ++++++++++++++++++++++++++++++++++++++++++
+ sound/soc/codecs/tas5713.c | 371 ++++++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/tas5713.h | 210 ++++++++++++++++++++++++
- 7 files changed, 723 insertions(+)
+ 7 files changed, 725 insertions(+)
create mode 100644 sound/soc/bcm/hifiberry_amp.c
create mode 100644 sound/soc/codecs/tas5713.c
create mode 100644 sound/soc/codecs/tas5713.h
@@ -47,20 +51,21 @@ Some code to load the driver based on device-tree-overlays was missing. This is
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -12,11 +12,13 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-
+@@ -9,12 +9,14 @@ snd-soc-cygnus-objs := cygnus-pcm.o cygn
+ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-cygnus.o
+
+ # BCM2708 Machine Support
++snd-soc-hifiberry-amp-objs := hifiberry_amp.o
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
-+snd-soc-hifiberry-amp-objs := hifiberry_amp.o
snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
-+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
- obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
- obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
--- /dev/null
+++ b/sound/soc/bcm/hifiberry_amp.c
@@ -0,0 +1,129 @@
@@ -233,7 +238,7 @@ Some code to load the driver based on device-tree-overlays was missing. This is
obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
--- /dev/null
+++ b/sound/soc/codecs/tas5713.c
-@@ -0,0 +1,369 @@
+@@ -0,0 +1,371 @@
+/*
+ * ASoC Driver for TAS5713
+ *
@@ -468,8 +473,10 @@ Some code to load the driver based on device-tree-overlays was missing. This is
+static struct snd_soc_codec_driver soc_codec_dev_tas5713 = {
+ .probe = tas5713_probe,
+ .remove = tas5713_remove,
-+ .controls = tas5713_snd_controls,
-+ .num_controls = ARRAY_SIZE(tas5713_snd_controls),
++ .component_driver = {
++ .controls = tas5713_snd_controls,
++ .num_controls = ARRAY_SIZE(tas5713_snd_controls),
++ },
+};
+
+
diff --git a/target/linux/brcm2708/patches-4.9/0074-Revert-Added-driver-for-HiFiBerry-Amp-amplifier-add-.patch b/target/linux/brcm2708/patches-4.9/0074-Revert-Added-driver-for-HiFiBerry-Amp-amplifier-add-.patch
deleted file mode 100644
index 412398731e..0000000000
--- a/target/linux/brcm2708/patches-4.9/0074-Revert-Added-driver-for-HiFiBerry-Amp-amplifier-add-.patch
+++ /dev/null
@@ -1,807 +0,0 @@
-From 321a000ddec470ccbe496e6ae2cdc65286d8f491 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix@gmail.com>
-Date: Mon, 12 Dec 2016 16:26:54 +0000
-Subject: [PATCH] Revert "Added driver for HiFiBerry Amp amplifier add-on
- board"
-
-This reverts commit 3e6b00833d92a50cbcc9922deb6e1bc8fcdbb587.
----
- sound/soc/bcm/Kconfig | 7 -
- sound/soc/bcm/Makefile | 2 -
- sound/soc/bcm/hifiberry_amp.c | 129 ---------------
- sound/soc/codecs/Kconfig | 4 -
- sound/soc/codecs/Makefile | 2 -
- sound/soc/codecs/tas5713.c | 369 ------------------------------------------
- sound/soc/codecs/tas5713.h | 210 ------------------------
- 7 files changed, 723 deletions(-)
- delete mode 100644 sound/soc/bcm/hifiberry_amp.c
- delete mode 100644 sound/soc/codecs/tas5713.c
- delete mode 100644 sound/soc/codecs/tas5713.h
-
---- a/sound/soc/bcm/Kconfig
-+++ b/sound/soc/bcm/Kconfig
-@@ -38,13 +38,6 @@ config SND_BCM2708_SOC_HIFIBERRY_DIGI
- help
- Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board.
-
--config SND_BCM2708_SOC_HIFIBERRY_AMP
-- tristate "Support for the HifiBerry Amp"
-- depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
-- select SND_SOC_TAS5713
-- help
-- Say Y or M if you want to add support for the HifiBerry Amp amplifier board.
--
- config SND_BCM2708_SOC_RPI_DAC
- tristate "Support for RPi-DAC"
- depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
---- a/sound/soc/bcm/Makefile
-+++ b/sound/soc/bcm/Makefile
-@@ -12,13 +12,11 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-
- snd-soc-hifiberry-dac-objs := hifiberry_dac.o
- snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
- snd-soc-hifiberry-digi-objs := hifiberry_digi.o
--snd-soc-hifiberry-amp-objs := hifiberry_amp.o
- snd-soc-rpi-dac-objs := rpi-dac.o
- snd-soc-iqaudio-dac-objs := iqaudio-dac.o
-
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
--obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
- obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
- obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
---- a/sound/soc/bcm/hifiberry_amp.c
-+++ /dev/null
-@@ -1,129 +0,0 @@
--/*
-- * ASoC Driver for HifiBerry AMP
-- *
-- * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
-- * Copyright 2014
-- *
-- * This program is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU General Public License
-- * version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful, but
-- * WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- * General Public License for more details.
-- */
--
--#include <linux/module.h>
--#include <linux/platform_device.h>
--
--#include <sound/core.h>
--#include <sound/pcm.h>
--#include <sound/pcm_params.h>
--#include <sound/soc.h>
--#include <sound/jack.h>
--
--static int snd_rpi_hifiberry_amp_init(struct snd_soc_pcm_runtime *rtd)
--{
-- // ToDo: init of the dsp-registers.
-- return 0;
--}
--
--static int snd_rpi_hifiberry_amp_hw_params( struct snd_pcm_substream *substream,
-- struct snd_pcm_hw_params *params )
--{
-- struct snd_soc_pcm_runtime *rtd = substream->private_data;
-- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
--
-- return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
--}
--
--static struct snd_soc_ops snd_rpi_hifiberry_amp_ops = {
-- .hw_params = snd_rpi_hifiberry_amp_hw_params,
--};
--
--static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = {
-- {
-- .name = "HifiBerry AMP",
-- .stream_name = "HifiBerry AMP HiFi",
-- .cpu_dai_name = "bcm2708-i2s.0",
-- .codec_dai_name = "tas5713-hifi",
-- .platform_name = "bcm2708-i2s.0",
-- .codec_name = "tas5713.1-001b",
-- .dai_fmt = SND_SOC_DAIFMT_I2S |
-- SND_SOC_DAIFMT_NB_NF |
-- SND_SOC_DAIFMT_CBS_CFS,
-- .ops = &snd_rpi_hifiberry_amp_ops,
-- .init = snd_rpi_hifiberry_amp_init,
-- },
--};
--
--
--static struct snd_soc_card snd_rpi_hifiberry_amp = {
-- .name = "snd_rpi_hifiberry_amp",
-- .driver_name = "HifiberryAmp",
-- .owner = THIS_MODULE,
-- .dai_link = snd_rpi_hifiberry_amp_dai,
-- .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai),
--};
--
--static const struct of_device_id snd_rpi_hifiberry_amp_of_match[] = {
-- { .compatible = "hifiberry,hifiberry-amp", },
-- {},
--};
--MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_amp_of_match);
--
--
--static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev)
--{
-- int ret = 0;
--
-- snd_rpi_hifiberry_amp.dev = &pdev->dev;
--
-- if (pdev->dev.of_node) {
-- struct device_node *i2s_node;
-- struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_amp_dai[0];
-- i2s_node = of_parse_phandle(pdev->dev.of_node,
-- "i2s-controller", 0);
--
-- if (i2s_node) {
-- dai->cpu_dai_name = NULL;
-- dai->cpu_of_node = i2s_node;
-- dai->platform_name = NULL;
-- dai->platform_of_node = i2s_node;
-- }
-- }
--
-- ret = snd_soc_register_card(&snd_rpi_hifiberry_amp);
--
-- if (ret != 0) {
-- dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
-- }
--
-- return ret;
--}
--
--
--static int snd_rpi_hifiberry_amp_remove(struct platform_device *pdev)
--{
-- return snd_soc_unregister_card(&snd_rpi_hifiberry_amp);
--}
--
--
--static struct platform_driver snd_rpi_hifiberry_amp_driver = {
-- .driver = {
-- .name = "snd-hifiberry-amp",
-- .owner = THIS_MODULE,
-- .of_match_table = snd_rpi_hifiberry_amp_of_match,
-- },
-- .probe = snd_rpi_hifiberry_amp_probe,
-- .remove = snd_rpi_hifiberry_amp_remove,
--};
--
--
--module_platform_driver(snd_rpi_hifiberry_amp_driver);
--
--
--MODULE_AUTHOR("Sebastian Eickhoff <basti.eickhoff@googlemail.com>");
--MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP");
--MODULE_LICENSE("GPL v2");
---- a/sound/soc/codecs/Kconfig
-+++ b/sound/soc/codecs/Kconfig
-@@ -139,7 +139,6 @@ config SND_SOC_ALL_CODECS
- select SND_SOC_TFA9879 if I2C
- select SND_SOC_TLV320AIC23_I2C if I2C
- select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
-- select SND_SOC_TAS5713 if I2C
- select SND_SOC_TLV320AIC26 if SPI_MASTER
- select SND_SOC_TLV320AIC31XX if I2C
- select SND_SOC_TLV320AIC32X4_I2C if I2C
-@@ -822,9 +821,6 @@ config SND_SOC_TFA9879
- tristate "NXP Semiconductors TFA9879 amplifier"
- depends on I2C
-
--config SND_SOC_TAS5713
-- tristate
--
- config SND_SOC_TLV320AIC23
- tristate
-
---- a/sound/soc/codecs/Makefile
-+++ b/sound/soc/codecs/Makefile
-@@ -144,7 +144,6 @@ snd-soc-tas5086-objs := tas5086.o
- snd-soc-tas571x-objs := tas571x.o
- snd-soc-tas5720-objs := tas5720.o
- snd-soc-tfa9879-objs := tfa9879.o
--snd-soc-tas5713-objs := tas5713.o
- snd-soc-tlv320aic23-objs := tlv320aic23.o
- snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
- snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
-@@ -367,7 +366,6 @@ obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc
- obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
- obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
- obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o
--obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o
- obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
- obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
- obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
---- a/sound/soc/codecs/tas5713.c
-+++ /dev/null
-@@ -1,369 +0,0 @@
--/*
-- * ASoC Driver for TAS5713
-- *
-- * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
-- * Copyright 2014
-- *
-- * This program is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU General Public License
-- * version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful, but
-- * WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- * General Public License for more details.
-- */
--
--#include <linux/module.h>
--#include <linux/moduleparam.h>
--#include <linux/init.h>
--#include <linux/delay.h>
--#include <linux/pm.h>
--#include <linux/i2c.h>
--#include <linux/of_device.h>
--#include <linux/spi/spi.h>
--#include <linux/regmap.h>
--#include <linux/regulator/consumer.h>
--#include <linux/slab.h>
--#include <sound/core.h>
--#include <sound/pcm.h>
--#include <sound/pcm_params.h>
--#include <sound/soc.h>
--#include <sound/initval.h>
--#include <sound/tlv.h>
--
--#include <linux/kernel.h>
--#include <linux/string.h>
--#include <linux/fs.h>
--#include <asm/uaccess.h>
--
--#include "tas5713.h"
--
--
--static struct i2c_client *i2c;
--
--struct tas5713_priv {
-- struct regmap *regmap;
-- int mclk_div;
-- struct snd_soc_codec *codec;
--};
--
--static struct tas5713_priv *priv_data;
--
--
--
--
--/*
-- * _ _ ___ _ ___ _ _
-- * /_\ | | / __| /_\ / __|___ _ _| |_ _ _ ___| |___
-- * / _ \| |__\__ \/ _ \ | (__/ _ \ ' \ _| '_/ _ \ (_-<
-- * /_/ \_\____|___/_/ \_\ \___\___/_||_\__|_| \___/_/__/
-- *
-- */
--
--static const DECLARE_TLV_DB_SCALE(tas5713_vol_tlv, -10000, 50, 1);
--
--
--static const struct snd_kcontrol_new tas5713_snd_controls[] = {
-- SOC_SINGLE_TLV ("Master" , TAS5713_VOL_MASTER, 0, 248, 1, tas5713_vol_tlv),
-- SOC_DOUBLE_R_TLV("Channels" , TAS5713_VOL_CH1, TAS5713_VOL_CH2, 0, 248, 1, tas5713_vol_tlv)
--};
--
--
--
--
--/*
-- * __ __ _ _ ___ _
-- * | \/ |__ _ __| |_ (_)_ _ ___ | \ _ _(_)_ _____ _ _
-- * | |\/| / _` / _| ' \| | ' \/ -_) | |) | '_| \ V / -_) '_|
-- * |_| |_\__,_\__|_||_|_|_||_\___| |___/|_| |_|\_/\___|_|
-- *
-- */
--
--static int tas5713_hw_params(struct snd_pcm_substream *substream,
-- struct snd_pcm_hw_params *params,
-- struct snd_soc_dai *dai)
--{
-- u16 blen = 0x00;
--
-- struct snd_soc_codec *codec;
-- codec = dai->codec;
-- priv_data->codec = dai->codec;
--
-- switch (params_format(params)) {
-- case SNDRV_PCM_FORMAT_S16_LE:
-- blen = 0x03;
-- break;
-- case SNDRV_PCM_FORMAT_S20_3LE:
-- blen = 0x1;
-- break;
-- case SNDRV_PCM_FORMAT_S24_LE:
-- blen = 0x04;
-- break;
-- case SNDRV_PCM_FORMAT_S32_LE:
-- blen = 0x05;
-- break;
-- default:
-- dev_err(dai->dev, "Unsupported word length: %u\n",
-- params_format(params));
-- return -EINVAL;
-- }
--
-- // set word length
-- snd_soc_update_bits(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x7, blen);
--
-- return 0;
--}
--
--
--static int tas5713_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
--{
-- unsigned int val = 0;
--
-- struct tas5713_priv *tas5713;
-- struct snd_soc_codec *codec = dai->codec;
-- tas5713 = snd_soc_codec_get_drvdata(codec);
--
-- if (mute) {
-- val = TAS5713_SOFT_MUTE_ALL;
-- }
--
-- return regmap_write(tas5713->regmap, TAS5713_SOFT_MUTE, val);
--}
--
--
--static const struct snd_soc_dai_ops tas5713_dai_ops = {
-- .hw_params = tas5713_hw_params,
-- .mute_stream = tas5713_mute_stream,
--};
--
--
--static struct snd_soc_dai_driver tas5713_dai = {
-- .name = "tas5713-hifi",
-- .playback = {
-- .stream_name = "Playback",
-- .channels_min = 2,
-- .channels_max = 2,
-- .rates = SNDRV_PCM_RATE_8000_48000,
-- .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE ),
-- },
-- .ops = &tas5713_dai_ops,
--};
--
--
--
--
--/*
-- * ___ _ ___ _
-- * / __|___ __| |___ __ | \ _ _(_)_ _____ _ _
-- * | (__/ _ \/ _` / -_) _| | |) | '_| \ V / -_) '_|
-- * \___\___/\__,_\___\__| |___/|_| |_|\_/\___|_|
-- *
-- */
--
--static int tas5713_remove(struct snd_soc_codec *codec)
--{
-- struct tas5713_priv *tas5713;
--
-- tas5713 = snd_soc_codec_get_drvdata(codec);
--
-- return 0;
--}
--
--
--static int tas5713_probe(struct snd_soc_codec *codec)
--{
-- struct tas5713_priv *tas5713;
-- int i, ret;
--
-- i2c = container_of(codec->dev, struct i2c_client, dev);
--
-- tas5713 = snd_soc_codec_get_drvdata(codec);
--
-- // Reset error
-- ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
-- if (ret < 0) return ret;
--
-- // Trim oscillator
-- ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00);
-- if (ret < 0) return ret;
-- msleep(1000);
--
-- // Reset error
-- ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
-- if (ret < 0) return ret;
--
-- // Clock mode: 44/48kHz, MCLK=64xfs
-- ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60);
-- if (ret < 0) return ret;
--
-- // I2S 24bit
-- ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05);
-- if (ret < 0) return ret;
--
-- // Unmute
-- ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
-- if (ret < 0) return ret;
-- ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00);
-- if (ret < 0) return ret;
--
-- // Set volume to 0db
-- ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00);
-- if (ret < 0) return ret;
--
-- // Now start programming the default initialization sequence
-- for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) {
-- ret = i2c_master_send(i2c,
-- tas5713_init_sequence[i].data,
-- tas5713_init_sequence[i].size);
-- if (ret < 0) {
-- printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret);
-- }
-- }
--
-- // Unmute
-- ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
-- if (ret < 0) return ret;
--
-- return 0;
--}
--
--
--static struct snd_soc_codec_driver soc_codec_dev_tas5713 = {
-- .probe = tas5713_probe,
-- .remove = tas5713_remove,
-- .controls = tas5713_snd_controls,
-- .num_controls = ARRAY_SIZE(tas5713_snd_controls),
--};
--
--
--
--
--/*
-- * ___ ___ ___ ___ _
-- * |_ _|_ ) __| | \ _ _(_)_ _____ _ _
-- * | | / / (__ | |) | '_| \ V / -_) '_|
-- * |___/___\___| |___/|_| |_|\_/\___|_|
-- *
-- */
--
--static const struct reg_default tas5713_reg_defaults[] = {
-- { 0x07 ,0x80 }, // R7 - VOL_MASTER - -40dB
-- { 0x08 , 30 }, // R8 - VOL_CH1 - 0dB
-- { 0x09 , 30 }, // R9 - VOL_CH2 - 0dB
-- { 0x0A ,0x80 }, // R10 - VOL_HEADPHONE - -40dB
--};
--
--
--static bool tas5713_reg_volatile(struct device *dev, unsigned int reg)
--{
-- switch (reg) {
-- case TAS5713_DEVICE_ID:
-- case TAS5713_ERROR_STATUS:
-- return true;
-- default:
-- return false;
-- }
--}
--
--
--static const struct of_device_id tas5713_of_match[] = {
-- { .compatible = "ti,tas5713", },
-- { }
--};
--MODULE_DEVICE_TABLE(of, tas5713_of_match);
--
--
--static struct regmap_config tas5713_regmap_config = {
-- .reg_bits = 8,
-- .val_bits = 8,
--
-- .max_register = TAS5713_MAX_REGISTER,
-- .volatile_reg = tas5713_reg_volatile,
--
-- .cache_type = REGCACHE_RBTREE,
-- .reg_defaults = tas5713_reg_defaults,
-- .num_reg_defaults = ARRAY_SIZE(tas5713_reg_defaults),
--};
--
--
--static int tas5713_i2c_probe(struct i2c_client *i2c,
-- const struct i2c_device_id *id)
--{
-- int ret;
--
-- priv_data = devm_kzalloc(&i2c->dev, sizeof *priv_data, GFP_KERNEL);
-- if (!priv_data)
-- return -ENOMEM;
--
-- priv_data->regmap = devm_regmap_init_i2c(i2c, &tas5713_regmap_config);
-- if (IS_ERR(priv_data->regmap)) {
-- ret = PTR_ERR(priv_data->regmap);
-- return ret;
-- }
--
-- i2c_set_clientdata(i2c, priv_data);
--
-- ret = snd_soc_register_codec(&i2c->dev,
-- &soc_codec_dev_tas5713, &tas5713_dai, 1);
--
-- return ret;
--}
--
--
--static int tas5713_i2c_remove(struct i2c_client *i2c)
--{
-- snd_soc_unregister_codec(&i2c->dev);
-- i2c_set_clientdata(i2c, NULL);
--
-- kfree(priv_data);
--
-- return 0;
--}
--
--
--static const struct i2c_device_id tas5713_i2c_id[] = {
-- { "tas5713", 0 },
-- { }
--};
--
--MODULE_DEVICE_TABLE(i2c, tas5713_i2c_id);
--
--
--static struct i2c_driver tas5713_i2c_driver = {
-- .driver = {
-- .name = "tas5713",
-- .owner = THIS_MODULE,
-- .of_match_table = tas5713_of_match,
-- },
-- .probe = tas5713_i2c_probe,
-- .remove = tas5713_i2c_remove,
-- .id_table = tas5713_i2c_id
--};
--
--
--static int __init tas5713_modinit(void)
--{
-- int ret = 0;
--
-- ret = i2c_add_driver(&tas5713_i2c_driver);
-- if (ret) {
-- printk(KERN_ERR "Failed to register tas5713 I2C driver: %d\n",
-- ret);
-- }
--
-- return ret;
--}
--module_init(tas5713_modinit);
--
--
--static void __exit tas5713_exit(void)
--{
-- i2c_del_driver(&tas5713_i2c_driver);
--}
--module_exit(tas5713_exit);
--
--
--MODULE_AUTHOR("Sebastian Eickhoff <basti.eickhoff@googlemail.com>");
--MODULE_DESCRIPTION("ASoC driver for TAS5713");
--MODULE_LICENSE("GPL v2");
---- a/sound/soc/codecs/tas5713.h
-+++ /dev/null
-@@ -1,210 +0,0 @@
--/*
-- * ASoC Driver for TAS5713
-- *
-- * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
-- * Copyright 2014
-- *
-- * This program is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU General Public License
-- * version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful, but
-- * WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- * General Public License for more details.
-- */
--
--#ifndef _TAS5713_H
--#define _TAS5713_H
--
--
--// TAS5713 I2C-bus register addresses
--
--#define TAS5713_CLOCK_CTRL 0x00
--#define TAS5713_DEVICE_ID 0x01
--#define TAS5713_ERROR_STATUS 0x02
--#define TAS5713_SYSTEM_CTRL1 0x03
--#define TAS5713_SERIAL_DATA_INTERFACE 0x04
--#define TAS5713_SYSTEM_CTRL2 0x05
--#define TAS5713_SOFT_MUTE 0x06
--#define TAS5713_VOL_MASTER 0x07
--#define TAS5713_VOL_CH1 0x08
--#define TAS5713_VOL_CH2 0x09
--#define TAS5713_VOL_HEADPHONE 0x0A
--#define TAS5713_VOL_CONFIG 0x0E
--#define TAS5713_MODULATION_LIMIT 0x10
--#define TAS5713_IC_DLY_CH1 0x11
--#define TAS5713_IC_DLY_CH2 0x12
--#define TAS5713_IC_DLY_CH3 0x13
--#define TAS5713_IC_DLY_CH4 0x14
--
--#define TAS5713_START_STOP_PERIOD 0x1A
--#define TAS5713_OSC_TRIM 0x1B
--#define TAS5713_BKND_ERR 0x1C
--
--#define TAS5713_INPUT_MUX 0x20
--#define TAS5713_SRC_SELECT_CH4 0x21
--#define TAS5713_PWM_MUX 0x25
--
--#define TAS5713_CH1_BQ0 0x29
--#define TAS5713_CH1_BQ1 0x2A
--#define TAS5713_CH1_BQ2 0x2B
--#define TAS5713_CH1_BQ3 0x2C
--#define TAS5713_CH1_BQ4 0x2D
--#define TAS5713_CH1_BQ5 0x2E
--#define TAS5713_CH1_BQ6 0x2F
--#define TAS5713_CH1_BQ7 0x58
--#define TAS5713_CH1_BQ8 0x59
--
--#define TAS5713_CH2_BQ0 0x30
--#define TAS5713_CH2_BQ1 0x31
--#define TAS5713_CH2_BQ2 0x32
--#define TAS5713_CH2_BQ3 0x33
--#define TAS5713_CH2_BQ4 0x34
--#define TAS5713_CH2_BQ5 0x35
--#define TAS5713_CH2_BQ6 0x36
--#define TAS5713_CH2_BQ7 0x5C
--#define TAS5713_CH2_BQ8 0x5D
--
--#define TAS5713_CH4_BQ0 0x5A
--#define TAS5713_CH4_BQ1 0x5B
--#define TAS5713_CH3_BQ0 0x5E
--#define TAS5713_CH3_BQ1 0x5F
--
--#define TAS5713_DRC1_SOFTENING_FILTER_ALPHA_OMEGA 0x3B
--#define TAS5713_DRC1_ATTACK_RELEASE_RATE 0x3C
--#define TAS5713_DRC2_SOFTENING_FILTER_ALPHA_OMEGA 0x3E
--#define TAS5713_DRC2_ATTACK_RELEASE_RATE 0x3F
--#define TAS5713_DRC1_ATTACK_RELEASE_THRES 0x40
--#define TAS5713_DRC2_ATTACK_RELEASE_THRES 0x43
--#define TAS5713_DRC_CTRL 0x46
--
--#define TAS5713_BANK_SW_CTRL 0x50
--#define TAS5713_CH1_OUTPUT_MIXER 0x51
--#define TAS5713_CH2_OUTPUT_MIXER 0x52
--#define TAS5713_CH1_INPUT_MIXER 0x53
--#define TAS5713_CH2_INPUT_MIXER 0x54
--#define TAS5713_OUTPUT_POST_SCALE 0x56
--#define TAS5713_OUTPUT_PRESCALE 0x57
--
--#define TAS5713_IDF_POST_SCALE 0x62
--
--#define TAS5713_CH1_INLINE_MIXER 0x70
--#define TAS5713_CH1_INLINE_DRC_EN_MIXER 0x71
--#define TAS5713_CH1_R_CHANNEL_MIXER 0x72
--#define TAS5713_CH1_L_CHANNEL_MIXER 0x73
--#define TAS5713_CH2_INLINE_MIXER 0x74
--#define TAS5713_CH2_INLINE_DRC_EN_MIXER 0x75
--#define TAS5713_CH2_L_CHANNEL_MIXER 0x76
--#define TAS5713_CH2_R_CHANNEL_MIXER 0x77
--
--#define TAS5713_UPDATE_DEV_ADDR_KEY 0xF8
--#define TAS5713_UPDATE_DEV_ADDR_REG 0xF9
--
--#define TAS5713_REGISTER_COUNT 0x46
--#define TAS5713_MAX_REGISTER 0xF9
--
--
--// Bitmasks for registers
--#define TAS5713_SOFT_MUTE_ALL 0x07
--
--
--
--struct tas5713_init_command {
-- const int size;
-- const char *const data;
--};
--
--static const struct tas5713_init_command tas5713_init_sequence[] = {
--
-- // Trim oscillator
-- { .size = 2, .data = "\x1B\x00" },
-- // System control register 1 (0x03): block DC
-- { .size = 2, .data = "\x03\x80" },
-- // Mute everything
-- { .size = 2, .data = "\x05\x40" },
-- // Modulation limit register (0x10): 97.7%
-- { .size = 2, .data = "\x10\x02" },
-- // Interchannel delay registers
-- // (0x11, 0x12, 0x13, and 0x14): BD mode
-- { .size = 2, .data = "\x11\xB8" },
-- { .size = 2, .data = "\x12\x60" },
-- { .size = 2, .data = "\x13\xA0" },
-- { .size = 2, .data = "\x14\x48" },
-- // PWM shutdown group register (0x19): no shutdown
-- { .size = 2, .data = "\x19\x00" },
-- // Input multiplexer register (0x20): BD mode
-- { .size = 2, .data = "\x20\x00\x89\x77\x72" },
-- // PWM output mux register (0x25)
-- // Channel 1 --> OUTA, channel 1 neg --> OUTB
-- // Channel 2 --> OUTC, channel 2 neg --> OUTD
-- { .size = 5, .data = "\x25\x01\x02\x13\x45" },
-- // DRC control (0x46): DRC off
-- { .size = 5, .data = "\x46\x00\x00\x00\x00" },
-- // BKND_ERR register (0x1C): 299ms reset period
-- { .size = 2, .data = "\x1C\x07" },
-- // Mute channel 3
-- { .size = 2, .data = "\x0A\xFF" },
-- // Volume configuration register (0x0E): volume slew 512 steps
-- { .size = 2, .data = "\x0E\x90" },
-- // Clock control register (0x00): 44/48kHz, MCLK=64xfs
-- { .size = 2, .data = "\x00\x60" },
-- // Bank switch and eq control (0x50): no bank switching
-- { .size = 5, .data = "\x50\x00\x00\x00\x00" },
-- // Volume registers (0x07, 0x08, 0x09, 0x0A)
-- { .size = 2, .data = "\x07\x20" },
-- { .size = 2, .data = "\x08\x30" },
-- { .size = 2, .data = "\x09\x30" },
-- { .size = 2, .data = "\x0A\xFF" },
-- // 0x72, 0x73, 0x76, 0x77 input mixer:
-- // no intermix between channels
-- { .size = 5, .data = "\x72\x00\x00\x00\x00" },
-- { .size = 5, .data = "\x73\x00\x80\x00\x00" },
-- { .size = 5, .data = "\x76\x00\x00\x00\x00" },
-- { .size = 5, .data = "\x77\x00\x80\x00\x00" },
-- // 0x70, 0x71, 0x74, 0x75 inline DRC mixer:
-- // no inline DRC inmix
-- { .size = 5, .data = "\x70\x00\x80\x00\x00" },
-- { .size = 5, .data = "\x71\x00\x00\x00\x00" },
-- { .size = 5, .data = "\x74\x00\x80\x00\x00" },
-- { .size = 5, .data = "\x75\x00\x00\x00\x00" },
-- // 0x56, 0x57 Output scale
-- { .size = 5, .data = "\x56\x00\x80\x00\x00" },
-- { .size = 5, .data = "\x57\x00\x02\x00\x00" },
-- // 0x3B, 0x3c
-- { .size = 9, .data = "\x3B\x00\x08\x00\x00\x00\x78\x00\x00" },
-- { .size = 9, .data = "\x3C\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-- { .size = 9, .data = "\x3E\x00\x08\x00\x00\x00\x78\x00\x00" },
-- { .size = 9, .data = "\x3F\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-- { .size = 9, .data = "\x40\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-- { .size = 9, .data = "\x43\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-- // 0x51, 0x52: output mixer
-- { .size = 9, .data = "\x51\x00\x80\x00\x00\x00\x00\x00\x00" },
-- { .size = 9, .data = "\x52\x00\x80\x00\x00\x00\x00\x00\x00" },
-- // PEQ defaults
-- { .size = 21, .data = "\x29\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x2A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x2B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x2C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x2D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x2E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x2F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x30\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x31\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x32\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x33\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x34\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x35\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x36\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x58\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x59\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x5C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x5D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x5E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x5F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x5A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-- { .size = 21, .data = "\x5B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
--};
--
--
--#endif /* _TAS5713_H */
diff --git a/target/linux/brcm2708/patches-4.9/0075-Update-ds1307-driver-for-device-tree-support.patch b/target/linux/brcm2708/patches-4.9/0074-Update-ds1307-driver-for-device-tree-support.patch
index 1dfed15876..d4f7e762c2 100644
--- a/target/linux/brcm2708/patches-4.9/0075-Update-ds1307-driver-for-device-tree-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0074-Update-ds1307-driver-for-device-tree-support.patch
@@ -1,4 +1,4 @@
-From 682c095597876ff7d669f92dc2a0f1f49526444c Mon Sep 17 00:00:00 2001
+From b3ff56f28a9531048812a51ded7c16a952d1ead4 Mon Sep 17 00:00:00 2001
From: Ryan Coe <bluemrp9@gmail.com>
Date: Sat, 31 Jan 2015 18:25:49 -0700
Subject: [PATCH] Update ds1307 driver for device-tree support
diff --git a/target/linux/brcm2708/patches-4.9/0076-Add-driver-for-rpi-proto.patch b/target/linux/brcm2708/patches-4.9/0075-Add-driver-for-rpi-proto.patch
index b23ff22d34..b8db1d5608 100644
--- a/target/linux/brcm2708/patches-4.9/0076-Add-driver-for-rpi-proto.patch
+++ b/target/linux/brcm2708/patches-4.9/0075-Add-driver-for-rpi-proto.patch
@@ -1,4 +1,4 @@
-From 001f8b8dc231bf3e20fd6802e2664788891ed8c4 Mon Sep 17 00:00:00 2001
+From b351d2ffe294c9d5e8cde9caa3a94017ecec81d9 Mon Sep 17 00:00:00 2001
From: Waldemar Brodkorb <wbrodkorb@conet.de>
Date: Wed, 25 Mar 2015 09:26:17 +0100
Subject: [PATCH] Add driver for rpi-proto
@@ -22,7 +22,7 @@ Signed-off-by: Waldemar Brodkorb <wbrodkorb@conet.de>
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -45,6 +45,13 @@ config SND_BCM2708_SOC_RPI_DAC
+@@ -52,6 +52,13 @@ config SND_BCM2708_SOC_RPI_DAC
help
Say Y or M if you want to add support for RPi-DAC.
@@ -38,14 +38,15 @@ Signed-off-by: Waldemar Brodkorb <wbrodkorb@conet.de>
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -13,10 +13,12 @@ snd-soc-hifiberry-dac-objs := hifiberry_
+@@ -14,6 +14,7 @@ snd-soc-hifiberry-dac-objs := hifiberry_
snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
snd-soc-rpi-dac-objs := rpi-dac.o
+snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
+@@ -21,4 +22,5 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
diff --git a/target/linux/brcm2708/patches-4.9/0077-RaspiDAC3-support.patch b/target/linux/brcm2708/patches-4.9/0076-RaspiDAC3-support.patch
index 32bc86af9b..de68bbf6b6 100644
--- a/target/linux/brcm2708/patches-4.9/0077-RaspiDAC3-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0076-RaspiDAC3-support.patch
@@ -1,4 +1,4 @@
-From 26084a968083e88298416426576dbd4c006e5dea Mon Sep 17 00:00:00 2001
+From b545537294ffc7e21fcc5e0c78ea8ac20c9ecd3f Mon Sep 17 00:00:00 2001
From: Jan Grulich <jan@grulich.eu>
Date: Mon, 24 Aug 2015 16:03:47 +0100
Subject: [PATCH] RaspiDAC3 support
@@ -20,7 +20,7 @@ Signed-off-by: Matthias Reichl <hias@horus.com>
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -58,3 +58,11 @@ config SND_BCM2708_SOC_IQAUDIO_DAC
+@@ -65,3 +65,11 @@ config SND_BCM2708_SOC_IQAUDIO_DAC
select SND_SOC_PCM512x_I2C
help
Say Y or M if you want to add support for IQaudIO-DAC.
@@ -34,15 +34,15 @@ Signed-off-by: Matthias Reichl <hias@horus.com>
+ Say Y or M if you want to add support for RaspiDAC Rev.3x.
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -15,6 +15,7 @@ snd-soc-hifiberry-digi-objs := hifiberry
+@@ -16,6 +16,7 @@ snd-soc-hifiberry-digi-objs := hifiberry
snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
+snd-soc-raspidac3-objs := raspidac3.o
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
-@@ -22,3 +23,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D
+@@ -24,3 +25,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_D
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
diff --git a/target/linux/brcm2708/patches-4.9/0078-Add-Support-for-JustBoom-Audio-boards.patch b/target/linux/brcm2708/patches-4.9/0077-Add-Support-for-JustBoom-Audio-boards.patch
index 95bf9a53c2..96545872f1 100644
--- a/target/linux/brcm2708/patches-4.9/0078-Add-Support-for-JustBoom-Audio-boards.patch
+++ b/target/linux/brcm2708/patches-4.9/0077-Add-Support-for-JustBoom-Audio-boards.patch
@@ -1,4 +1,4 @@
-From 16e3f935b10cbd118056806ebd3afe6eed4c0183 Mon Sep 17 00:00:00 2001
+From 4a8ebf575ea143c14fd815ecd1f5398b6a6aee67 Mon Sep 17 00:00:00 2001
From: Aaron Shaw <shawaj@gmail.com>
Date: Thu, 7 Apr 2016 21:26:21 +0100
Subject: [PATCH] Add Support for JustBoom Audio boards
@@ -20,7 +20,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -52,6 +52,20 @@ config SND_BCM2708_SOC_RPI_PROTO
+@@ -59,6 +59,20 @@ config SND_BCM2708_SOC_RPI_PROTO
help
Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731).
@@ -43,7 +43,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -12,6 +12,8 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-
+@@ -13,6 +13,8 @@ snd-soc-hifiberry-amp-objs := hifiberry_
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
snd-soc-hifiberry-digi-objs := hifiberry_digi.o
@@ -52,7 +52,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
-@@ -20,6 +22,8 @@ snd-soc-raspidac3-objs := raspidac3.o
+@@ -22,6 +24,8 @@ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_A
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
diff --git a/target/linux/brcm2708/patches-4.9/0079-ARM-adau1977-adc-Add-basic-machine-driver-for-adau19.patch b/target/linux/brcm2708/patches-4.9/0078-ARM-adau1977-adc-Add-basic-machine-driver-for-adau19.patch
index 54d659f015..1b87b13efd 100644
--- a/target/linux/brcm2708/patches-4.9/0079-ARM-adau1977-adc-Add-basic-machine-driver-for-adau19.patch
+++ b/target/linux/brcm2708/patches-4.9/0078-ARM-adau1977-adc-Add-basic-machine-driver-for-adau19.patch
@@ -1,4 +1,4 @@
-From 55bbfc45096c8046134a2062acb2dd0806f48250 Mon Sep 17 00:00:00 2001
+From 9bbd8a3c8378eac9e605e0f37f4005583e122527 Mon Sep 17 00:00:00 2001
From: Andrey Grodzovsky <andrey2805@gmail.com>
Date: Tue, 3 May 2016 22:10:59 -0400
Subject: [PATCH] ARM: adau1977-adc: Add basic machine driver for adau1977
@@ -18,7 +18,7 @@ Signed-off-by: Andrey Grodzovsky <andrey2805@gmail.com>
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -80,3 +80,10 @@ config SND_BCM2708_SOC_RASPIDAC3
+@@ -87,3 +87,10 @@ config SND_BCM2708_SOC_RASPIDAC3
select SND_SOC_TPA6130A2
help
Say Y or M if you want to add support for RaspiDAC Rev.3x.
@@ -36,17 +36,17 @@ Signed-off-by: Andrey Grodzovsky <andrey2805@gmail.com>
# BCM2708 Machine Support
+snd-soc-adau1977-adc-objs := adau1977-adc.o
+ snd-soc-hifiberry-amp-objs := hifiberry_amp.o
snd-soc-hifiberry-dac-objs := hifiberry_dac.o
snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
- snd-soc-hifiberry-digi-objs := hifiberry_digi.o
-@@ -19,6 +20,7 @@ snd-soc-rpi-proto-objs := rpi-proto.o
+@@ -20,6 +21,7 @@ snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
snd-soc-raspidac3-objs := raspidac3.o
+obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
--- /dev/null
+++ b/sound/soc/bcm/adau1977-adc.c
@@ -0,0 +1,125 @@
diff --git a/target/linux/brcm2708/patches-4.9/0080-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch b/target/linux/brcm2708/patches-4.9/0079-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch
index 207cc66588..71d4fef697 100644
--- a/target/linux/brcm2708/patches-4.9/0080-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch
+++ b/target/linux/brcm2708/patches-4.9/0079-New-AudioInjector.net-Pi-soundcard-with-low-jitter-a.patch
@@ -1,4 +1,4 @@
-From 14502b0564fc2e7181857de254a6f6bd07db4038 Mon Sep 17 00:00:00 2001
+From 235989cb582a29be0bea6a7e306f7b839789053c Mon Sep 17 00:00:00 2001
From: Matt Flax <flatmax@flatmax.org>
Date: Mon, 16 May 2016 21:36:31 +1000
Subject: [PATCH] New AudioInjector.net Pi soundcard with low jitter audio in
@@ -21,7 +21,7 @@ This patch adds headphone and microphone capability to the Audio Injector sound
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -87,3 +87,10 @@ config SND_BCM2708_SOC_ADAU1977_ADC
+@@ -94,3 +94,10 @@ config SND_BCM2708_SOC_ADAU1977_ADC
select SND_SOC_ADAU1977_I2C
help
Say Y or M if you want to add support for ADAU1977 ADC.
@@ -34,15 +34,15 @@ This patch adds headphone and microphone capability to the Audio Injector sound
+ Say Y or M if you want to add support for audioinjector.net Pi Hat
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -19,6 +19,7 @@ snd-soc-rpi-dac-objs := rpi-dac.o
+@@ -20,6 +20,7 @@ snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
snd-soc-raspidac3-objs := raspidac3.o
+snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
-@@ -30,3 +31,5 @@ obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) +=
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
+@@ -32,3 +33,5 @@ obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) +=
obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o
diff --git a/target/linux/brcm2708/patches-4.9/0081-Add-IQAudIO-Digi-WM8804-board-support.patch b/target/linux/brcm2708/patches-4.9/0080-Add-IQAudIO-Digi-WM8804-board-support.patch
index e931c992c7..f6a23f91f4 100644
--- a/target/linux/brcm2708/patches-4.9/0081-Add-IQAudIO-Digi-WM8804-board-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0080-Add-IQAudIO-Digi-WM8804-board-support.patch
@@ -1,4 +1,4 @@
-From 1b18f3be9f034c2e9aefab9b97c5100d5f914a89 Mon Sep 17 00:00:00 2001
+From 5d70e6012f390d6292ea8017cebb947a003fce00 Mon Sep 17 00:00:00 2001
From: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
Date: Thu, 30 Jun 2016 18:38:42 +0100
Subject: [PATCH] Add IQAudIO Digi WM8804 board support
@@ -19,7 +19,7 @@ Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -73,6 +73,13 @@ config SND_BCM2708_SOC_IQAUDIO_DAC
+@@ -80,6 +80,13 @@ config SND_BCM2708_SOC_IQAUDIO_DAC
help
Say Y or M if you want to add support for IQaudIO-DAC.
@@ -35,7 +35,7 @@ Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -18,6 +18,7 @@ snd-soc-justboom-digi-objs := justboom-d
+@@ -19,6 +19,7 @@ snd-soc-justboom-digi-objs := justboom-d
snd-soc-rpi-dac-objs := rpi-dac.o
snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
@@ -43,7 +43,7 @@ Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
snd-soc-raspidac3-objs := raspidac3.o
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
-@@ -30,6 +31,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DI
+@@ -32,6 +33,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DI
obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
diff --git a/target/linux/brcm2708/patches-4.9/0082-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch b/target/linux/brcm2708/patches-4.9/0081-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch
index 55d32df1c5..45a5a379be 100644
--- a/target/linux/brcm2708/patches-4.9/0082-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch
+++ b/target/linux/brcm2708/patches-4.9/0081-New-driver-for-RRA-DigiDAC1-soundcard-using-WM8741-W.patch
@@ -1,4 +1,4 @@
-From 6daac5c03a5a96f6ae711e90d46e3d5de3ba1298 Mon Sep 17 00:00:00 2001
+From e5d85d533e7ea8fd5c68d4601ff2b8034bc4aaa9 Mon Sep 17 00:00:00 2001
From: escalator2015 <jmtasende@gmail.com>
Date: Tue, 24 May 2016 16:20:09 +0100
Subject: [PATCH] New driver for RRA DigiDAC1 soundcard using WM8741 + WM8804
@@ -12,7 +12,7 @@ Subject: [PATCH] New driver for RRA DigiDAC1 soundcard using WM8741 + WM8804
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -101,3 +101,11 @@ config SND_AUDIOINJECTOR_PI_SOUNDCARD
+@@ -108,3 +108,11 @@ config SND_AUDIOINJECTOR_PI_SOUNDCARD
select SND_SOC_WM8731
help
Say Y or M if you want to add support for audioinjector.net Pi Hat
@@ -26,15 +26,15 @@ Subject: [PATCH] New driver for RRA DigiDAC1 soundcard using WM8741 + WM8804
+ Say Y or M if you want to add support for Red Rocks Audio DigiDAC1 board.
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -21,6 +21,7 @@ snd-soc-iqaudio-dac-objs := iqaudio-dac.
+@@ -22,6 +22,7 @@ snd-soc-iqaudio-dac-objs := iqaudio-dac.
snd-soc-iqaudio-digi-objs := iqaudio_digi.o
snd-soc-raspidac3-objs := raspidac3.o
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
+snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
-@@ -34,4 +35,5 @@ obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
+@@ -36,4 +37,5 @@ obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI) += snd-soc-iqaudio-digi.o
obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o
obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
diff --git a/target/linux/brcm2708/patches-4.9/0083-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch b/target/linux/brcm2708/patches-4.9/0082-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch
index 39366abe45..b06cd35b72 100644
--- a/target/linux/brcm2708/patches-4.9/0083-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch
+++ b/target/linux/brcm2708/patches-4.9/0082-Add-support-for-Dion-Audio-LOCO-DAC-AMP-HAT.patch
@@ -1,4 +1,4 @@
-From ce97723802a6e68483111819f29d777e0ff0b975 Mon Sep 17 00:00:00 2001
+From 999d3e615247d1921d245f7084194efbc697bb66 Mon Sep 17 00:00:00 2001
From: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
Date: Sat, 2 Jul 2016 16:26:19 +0100
Subject: [PATCH] Add support for Dion Audio LOCO DAC-AMP HAT
@@ -15,7 +15,7 @@ Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -109,3 +109,10 @@ config SND_DIGIDAC1_SOUNDCARD
+@@ -116,3 +116,10 @@ config SND_DIGIDAC1_SOUNDCARD
select SND_SOC_WM8741
help
Say Y or M if you want to add support for Red Rocks Audio DigiDAC1 board.
@@ -28,15 +28,15 @@ Signed-off-by: DigitalDreamtime <clive.messer@digitaldreamtime.co.uk>
+ Say Y or M if you want to add support for Dion Audio LOCO.
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -22,6 +22,7 @@ snd-soc-iqaudio-digi-objs := iqaudio_dig
+@@ -23,6 +23,7 @@ snd-soc-iqaudio-digi-objs := iqaudio_dig
snd-soc-raspidac3-objs := raspidac3.o
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
+snd-soc-dionaudio-loco-objs := dionaudio_loco.o
obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
-@@ -36,4 +37,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DIG
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
+@@ -38,4 +39,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DIG
obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3) += snd-soc-raspidac3.o
obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o
diff --git a/target/linux/brcm2708/patches-4.9/0084-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch b/target/linux/brcm2708/patches-4.9/0083-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch
index 7455fa92da..64e785d2a6 100644
--- a/target/linux/brcm2708/patches-4.9/0084-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch
+++ b/target/linux/brcm2708/patches-4.9/0083-Allo-Piano-DAC-boards-Initial-2-channel-stereo-suppo.patch
@@ -1,4 +1,4 @@
-From 203501a533e71e5f76f9e06c0f0b8bfb0fc27147 Mon Sep 17 00:00:00 2001
+From 779409817cf1af2c38055af64c11e026cb0bb4e9 Mon Sep 17 00:00:00 2001
From: Clive Messer <clive.m.messer@gmail.com>
Date: Mon, 19 Sep 2016 14:01:04 +0100
Subject: [PATCH] Allo Piano DAC boards: Initial 2 channel (stereo) support
@@ -27,7 +27,7 @@ Tested-by: Clive Messer <clive.messer@digitaldreamtime.co.uk>
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -116,3 +116,10 @@ config SND_BCM2708_SOC_DIONAUDIO_LOCO
+@@ -123,3 +123,10 @@ config SND_BCM2708_SOC_DIONAUDIO_LOCO
select SND_SOC_PCM5102a
help
Say Y or M if you want to add support for Dion Audio LOCO.
@@ -40,15 +40,15 @@ Tested-by: Clive Messer <clive.messer@digitaldreamtime.co.uk>
+ Say Y or M if you want to add support for Allo Piano DAC.
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -23,6 +23,7 @@ snd-soc-raspidac3-objs := raspidac3.o
+@@ -24,6 +24,7 @@ snd-soc-raspidac3-objs := raspidac3.o
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
snd-soc-dionaudio-loco-objs := dionaudio_loco.o
+snd-soc-allo-piano-dac-objs := allo-piano-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
-@@ -38,3 +39,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3)
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
+@@ -40,3 +41,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3)
obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o
obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o
diff --git a/target/linux/brcm2708/patches-4.9/0085-Support-for-Blokas-Labs-pisound-board.patch b/target/linux/brcm2708/patches-4.9/0084-Support-for-Blokas-Labs-pisound-board.patch
index 51d5733737..21f43347b3 100644
--- a/target/linux/brcm2708/patches-4.9/0085-Support-for-Blokas-Labs-pisound-board.patch
+++ b/target/linux/brcm2708/patches-4.9/0084-Support-for-Blokas-Labs-pisound-board.patch
@@ -1,4 +1,4 @@
-From aa46aa94c5ca5683fd815c57a78ea5fb05e7c3e5 Mon Sep 17 00:00:00 2001
+From 7d8efd6f3198fd3dafe5a74003616a2aea5dc6c5 Mon Sep 17 00:00:00 2001
From: gtrainavicius <gtrainavicius@users.noreply.github.com>
Date: Sun, 23 Oct 2016 12:06:53 +0300
Subject: [PATCH] Support for Blokas Labs pisound board
@@ -149,7 +149,7 @@ Print a logline when the kernel module is removed.
};
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
-@@ -123,3 +123,9 @@ config SND_BCM2708_SOC_ALLO_PIANO_DAC
+@@ -130,3 +130,9 @@ config SND_BCM2708_SOC_ALLO_PIANO_DAC
select SND_SOC_PCM512x_I2C
help
Say Y or M if you want to add support for Allo Piano DAC.
@@ -161,15 +161,15 @@ Print a logline when the kernel module is removed.
+ Say Y or M if you want to add support for Blokas Labs pisound.
--- a/sound/soc/bcm/Makefile
+++ b/sound/soc/bcm/Makefile
-@@ -24,6 +24,7 @@ snd-soc-audioinjector-pi-soundcard-objs
+@@ -25,6 +25,7 @@ snd-soc-audioinjector-pi-soundcard-objs
snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
snd-soc-dionaudio-loco-objs := dionaudio_loco.o
snd-soc-allo-piano-dac-objs := allo-piano-dac.o
+snd-soc-pisound-objs := pisound.o
obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
-@@ -40,3 +41,4 @@ obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDC
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
+@@ -42,3 +43,4 @@ obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDC
obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o
obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o
obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o
diff --git a/target/linux/brcm2708/patches-4.9/0086-rpi_display-add-backlight-driver-and-overlay.patch b/target/linux/brcm2708/patches-4.9/0085-rpi_display-add-backlight-driver-and-overlay.patch
index 4706e7ae93..67c0e3f5cd 100644
--- a/target/linux/brcm2708/patches-4.9/0086-rpi_display-add-backlight-driver-and-overlay.patch
+++ b/target/linux/brcm2708/patches-4.9/0085-rpi_display-add-backlight-driver-and-overlay.patch
@@ -1,4 +1,4 @@
-From 42d919a6d8c63ca32dd6caee1288d58319e0e22e Mon Sep 17 00:00:00 2001
+From ae5ae9278768c3d096910705bfa9af85da20a8cf Mon Sep 17 00:00:00 2001
From: P33M <P33M@github.com>
Date: Wed, 21 Oct 2015 14:55:21 +0100
Subject: [PATCH] rpi_display: add backlight driver and overlay
diff --git a/target/linux/brcm2708/patches-4.9/0087-bcm2835-virtgpio-Virtual-GPIO-driver.patch b/target/linux/brcm2708/patches-4.9/0086-bcm2835-virtgpio-Virtual-GPIO-driver.patch
index ce523e289d..425224e5a5 100644
--- a/target/linux/brcm2708/patches-4.9/0087-bcm2835-virtgpio-Virtual-GPIO-driver.patch
+++ b/target/linux/brcm2708/patches-4.9/0086-bcm2835-virtgpio-Virtual-GPIO-driver.patch
@@ -1,4 +1,4 @@
-From 1b4e68b09ba226afac9414b11f89d3b833236e13 Mon Sep 17 00:00:00 2001
+From 1b6bee75a64ca43404e6bc8ff2fdbe8b1d0a0423 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Tue, 23 Feb 2016 19:56:04 +0000
Subject: [PATCH] bcm2835-virtgpio: Virtual GPIO driver
diff --git a/target/linux/brcm2708/patches-4.9/0088-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch b/target/linux/brcm2708/patches-4.9/0087-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch
index 1f69465d3e..40963de876 100644
--- a/target/linux/brcm2708/patches-4.9/0088-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch
+++ b/target/linux/brcm2708/patches-4.9/0087-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch
@@ -1,4 +1,4 @@
-From 0c3101c247b410c7e73dbb3ede7d0031fb622044 Mon Sep 17 00:00:00 2001
+From b34475b447c7e97fa9c4a854849f6e856fe59931 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 23 Feb 2016 17:26:48 +0000
Subject: [PATCH] amba_pl011: Don't use DT aliases for numbering
diff --git a/target/linux/brcm2708/patches-4.9/0091-OF-DT-Overlay-configfs-interface.patch b/target/linux/brcm2708/patches-4.9/0090-OF-DT-Overlay-configfs-interface.patch
index c864eba323..941047adc5 100644
--- a/target/linux/brcm2708/patches-4.9/0091-OF-DT-Overlay-configfs-interface.patch
+++ b/target/linux/brcm2708/patches-4.9/0090-OF-DT-Overlay-configfs-interface.patch
@@ -1,4 +1,4 @@
-From af8af738c62584683c75cbcbbd80ac4425c8986c Mon Sep 17 00:00:00 2001
+From ef4a8376af32bb6722e1ea933a9e1a83ebc8f175 Mon Sep 17 00:00:00 2001
From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Date: Wed, 3 Dec 2014 13:23:28 +0200
Subject: [PATCH] OF: DT-Overlay configfs interface
diff --git a/target/linux/brcm2708/patches-4.9/0093-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch b/target/linux/brcm2708/patches-4.9/0092-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch
index 0ebf29c7a3..780a211c8c 100644
--- a/target/linux/brcm2708/patches-4.9/0093-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch
+++ b/target/linux/brcm2708/patches-4.9/0092-hci_h5-Don-t-send-conf_req-when-ACTIVE.patch
@@ -1,4 +1,4 @@
-From 63e3b21d72b4542cd0f7527bbc7dc0aef13eb16d Mon Sep 17 00:00:00 2001
+From 0224b0469a7f5c2ee6420aac66e89e3206029633 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 17 Dec 2015 13:37:07 +0000
Subject: [PATCH] hci_h5: Don't send conf_req when ACTIVE
diff --git a/target/linux/brcm2708/patches-4.9/0094-config-Add-default-configs.patch b/target/linux/brcm2708/patches-4.9/0093-config-Add-default-configs.patch
index c940298c96..da92f04b4c 100644
--- a/target/linux/brcm2708/patches-4.9/0094-config-Add-default-configs.patch
+++ b/target/linux/brcm2708/patches-4.9/0093-config-Add-default-configs.patch
@@ -1,4 +1,4 @@
-From dcfe6cf60a2f84f321f64267f09f8a0f19b7a609 Mon Sep 17 00:00:00 2001
+From 9455097dbb0c961edb6a47b451e18a985f5d9a3f Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 13 Apr 2015 17:16:29 +0100
Subject: [PATCH] config: Add default configs
diff --git a/target/linux/brcm2708/patches-4.9/0095-Add-arm64-configuration-and-device-tree-differences.patch b/target/linux/brcm2708/patches-4.9/0094-Add-arm64-configuration-and-device-tree-differences.patch
index 9c76d38550..0cbb4d77f3 100644
--- a/target/linux/brcm2708/patches-4.9/0095-Add-arm64-configuration-and-device-tree-differences.patch
+++ b/target/linux/brcm2708/patches-4.9/0094-Add-arm64-configuration-and-device-tree-differences.patch
@@ -1,4 +1,4 @@
-From 24273c675c44f730b89416a40fac0aa35df6cfe0 Mon Sep 17 00:00:00 2001
+From 64d1c392baa391243d0a7963379ab957d5d9b8b1 Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran@crowfest.net>
Date: Wed, 24 Aug 2016 03:35:56 -0700
Subject: [PATCH] Add arm64 configuration and device tree differences. Disable
diff --git a/target/linux/brcm2708/patches-4.9/0096-vchiq_arm-Tweak-the-logging-output.patch b/target/linux/brcm2708/patches-4.9/0095-vchiq_arm-Tweak-the-logging-output.patch
index 294689bcf9..ef3c97ddc3 100644
--- a/target/linux/brcm2708/patches-4.9/0096-vchiq_arm-Tweak-the-logging-output.patch
+++ b/target/linux/brcm2708/patches-4.9/0095-vchiq_arm-Tweak-the-logging-output.patch
@@ -1,4 +1,4 @@
-From c5a316c09e241260f6131e0dc968209b053fcd56 Mon Sep 17 00:00:00 2001
+From 60486e8778192830c0e5369d4f05954c1f7cc12c Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 7 Mar 2016 15:05:11 +0000
Subject: [PATCH] vchiq_arm: Tweak the logging output
diff --git a/target/linux/brcm2708/patches-4.9/0097-vchiq_arm-Access-the-dequeue_pending-flag-locked.patch b/target/linux/brcm2708/patches-4.9/0096-vchiq_arm-Access-the-dequeue_pending-flag-locked.patch
index fef600b8b6..71c0e304dd 100644
--- a/target/linux/brcm2708/patches-4.9/0097-vchiq_arm-Access-the-dequeue_pending-flag-locked.patch
+++ b/target/linux/brcm2708/patches-4.9/0096-vchiq_arm-Access-the-dequeue_pending-flag-locked.patch
@@ -1,4 +1,4 @@
-From c451a1169c71ef984e367a81d619a7089dfb14e0 Mon Sep 17 00:00:00 2001
+From 64e39b18b8d51eb332a84ef79ed3ce0dd2a76808 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 23 Mar 2016 14:16:25 +0000
Subject: [PATCH] vchiq_arm: Access the dequeue_pending flag locked
diff --git a/target/linux/brcm2708/patches-4.9/0098-vchiq_arm-Service-callbacks-must-not-fail.patch b/target/linux/brcm2708/patches-4.9/0097-vchiq_arm-Service-callbacks-must-not-fail.patch
index 1f30478d98..f60af85307 100644
--- a/target/linux/brcm2708/patches-4.9/0098-vchiq_arm-Service-callbacks-must-not-fail.patch
+++ b/target/linux/brcm2708/patches-4.9/0097-vchiq_arm-Service-callbacks-must-not-fail.patch
@@ -1,4 +1,4 @@
-From db2437c557a5095022610b672c066aa2c16a684d Mon Sep 17 00:00:00 2001
+From e518e4dcd42f5a9e3b32a3a54c258320c4752d7e Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 23 Mar 2016 20:53:47 +0000
Subject: [PATCH] vchiq_arm: Service callbacks must not fail
diff --git a/target/linux/brcm2708/patches-4.9/0099-vchiq_arm-Add-completion-records-under-the-mutex.patch b/target/linux/brcm2708/patches-4.9/0098-vchiq_arm-Add-completion-records-under-the-mutex.patch
index ea1731bbfa..1b8647e86a 100644
--- a/target/linux/brcm2708/patches-4.9/0099-vchiq_arm-Add-completion-records-under-the-mutex.patch
+++ b/target/linux/brcm2708/patches-4.9/0098-vchiq_arm-Add-completion-records-under-the-mutex.patch
@@ -1,4 +1,4 @@
-From ed2a687b8fc8cd8c1154a9ae7c9fdb2e03176ed0 Mon Sep 17 00:00:00 2001
+From 152fc9447942bad4e2c6c1e6b86fd252689cc596 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Thu, 21 Apr 2016 13:49:32 +0100
Subject: [PATCH] vchiq_arm: Add completion records under the mutex
diff --git a/target/linux/brcm2708/patches-4.9/0100-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch b/target/linux/brcm2708/patches-4.9/0099-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch
index 55d2f68a26..c8cc5b7837 100644
--- a/target/linux/brcm2708/patches-4.9/0100-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch
+++ b/target/linux/brcm2708/patches-4.9/0099-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch
@@ -1,4 +1,4 @@
-From 59d2abf4834befa2d2ef8e8a37ab896df4a04868 Mon Sep 17 00:00:00 2001
+From 965475a1620ba1c4f19d6585925a40e3c749d7d1 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 20 Jun 2016 13:51:44 +0100
Subject: [PATCH] vchiq_arm: Avoid use of mutex in add_completion
diff --git a/target/linux/brcm2708/patches-4.9/0101-staging-vchi-Convert-to-current-get_user_pages-argum.patch b/target/linux/brcm2708/patches-4.9/0100-staging-vchi-Convert-to-current-get_user_pages-argum.patch
index e5d9528885..e80c414633 100644
--- a/target/linux/brcm2708/patches-4.9/0101-staging-vchi-Convert-to-current-get_user_pages-argum.patch
+++ b/target/linux/brcm2708/patches-4.9/0100-staging-vchi-Convert-to-current-get_user_pages-argum.patch
@@ -1,4 +1,4 @@
-From d2a51ea3b1f32cd7e53e20dbcd59aea48f09b1a6 Mon Sep 17 00:00:00 2001
+From ec643be82b145a65d9c78d24eea7470b9bb6e0c4 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 3 Oct 2016 10:14:10 -0700
Subject: [PATCH] staging/vchi: Convert to current get_user_pages() arguments.
diff --git a/target/linux/brcm2708/patches-4.9/0102-staging-vchi-Update-for-rename-of-page_cache_release.patch b/target/linux/brcm2708/patches-4.9/0101-staging-vchi-Update-for-rename-of-page_cache_release.patch
index 4be551f0ee..eccb792ee9 100644
--- a/target/linux/brcm2708/patches-4.9/0102-staging-vchi-Update-for-rename-of-page_cache_release.patch
+++ b/target/linux/brcm2708/patches-4.9/0101-staging-vchi-Update-for-rename-of-page_cache_release.patch
@@ -1,4 +1,4 @@
-From d47b4b7130260ada73a3520d43ca2df2032dc526 Mon Sep 17 00:00:00 2001
+From 5e8386a65d2b7fd157d2a6e2f9b8ca79011976b7 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 3 Oct 2016 10:16:03 -0700
Subject: [PATCH] staging/vchi: Update for rename of page_cache_release() to
diff --git a/target/linux/brcm2708/patches-4.9/0103-drivers-vchi-Remove-dependency-on-CONFIG_BROKEN.patch b/target/linux/brcm2708/patches-4.9/0102-drivers-vchi-Remove-dependency-on-CONFIG_BROKEN.patch
index 52fd44aa81..8ec807e065 100644
--- a/target/linux/brcm2708/patches-4.9/0103-drivers-vchi-Remove-dependency-on-CONFIG_BROKEN.patch
+++ b/target/linux/brcm2708/patches-4.9/0102-drivers-vchi-Remove-dependency-on-CONFIG_BROKEN.patch
@@ -1,4 +1,4 @@
-From b5282b49812b3f0ec18f2b998f6070b9af34edf6 Mon Sep 17 00:00:00 2001
+From b909c0f36c535e3f3042517d1b59b9c0538cc1d0 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Mon, 3 Oct 2016 10:21:17 -0700
Subject: [PATCH] drivers/vchi: Remove dependency on CONFIG_BROKEN.
diff --git a/target/linux/brcm2708/patches-4.9/0104-raspberrypi-firmware-Export-the-general-transaction-.patch b/target/linux/brcm2708/patches-4.9/0103-raspberrypi-firmware-Export-the-general-transaction-.patch
index 5dc6f85e95..a316b409c4 100644
--- a/target/linux/brcm2708/patches-4.9/0104-raspberrypi-firmware-Export-the-general-transaction-.patch
+++ b/target/linux/brcm2708/patches-4.9/0103-raspberrypi-firmware-Export-the-general-transaction-.patch
@@ -1,4 +1,4 @@
-From 207c380da679f31a62a1bb604dd22834d902acaf Mon Sep 17 00:00:00 2001
+From 34454ca8cf9b63b0973fb23271810461a45a9884 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Wed, 14 Sep 2016 09:16:19 +0100
Subject: [PATCH] raspberrypi-firmware: Export the general transaction
diff --git a/target/linux/brcm2708/patches-4.9/0105-raspberrypi-firmware-Define-the-MBOX-channel-in-the-.patch b/target/linux/brcm2708/patches-4.9/0104-raspberrypi-firmware-Define-the-MBOX-channel-in-the-.patch
index 0909929a2f..0b9ef71823 100644
--- a/target/linux/brcm2708/patches-4.9/0105-raspberrypi-firmware-Define-the-MBOX-channel-in-the-.patch
+++ b/target/linux/brcm2708/patches-4.9/0104-raspberrypi-firmware-Define-the-MBOX-channel-in-the-.patch
@@ -1,4 +1,4 @@
-From f918546b8d35b4051d79245027037492e15a7efe Mon Sep 17 00:00:00 2001
+From bf20c77c459b00873d5862cfe7ba745a543d53de Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Wed, 14 Sep 2016 09:18:09 +0100
Subject: [PATCH] raspberrypi-firmware: Define the MBOX channel in the header.
diff --git a/target/linux/brcm2708/patches-4.9/0106-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch b/target/linux/brcm2708/patches-4.9/0105-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch
index 3d1e684226..88952dc0c0 100644
--- a/target/linux/brcm2708/patches-4.9/0106-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch
+++ b/target/linux/brcm2708/patches-4.9/0105-drm-vc4-Add-a-mode-for-using-the-closed-firmware-for.patch
@@ -1,4 +1,4 @@
-From 12d493c17841adf193361623a64cd85804dea94f Mon Sep 17 00:00:00 2001
+From ffd9952ec22321af8e891aa4cf9d79d90c4b23b6 Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Wed, 14 Sep 2016 08:39:33 +0100
Subject: [PATCH] drm/vc4: Add a mode for using the closed firmware for
diff --git a/target/linux/brcm2708/patches-4.9/0107-i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch b/target/linux/brcm2708/patches-4.9/0106-i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch
index 7692a92467..899c75e0db 100644
--- a/target/linux/brcm2708/patches-4.9/0107-i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch
+++ b/target/linux/brcm2708/patches-4.9/0106-i2c-bcm2835-Fix-hang-for-writing-messages-larger-tha.patch
@@ -1,4 +1,4 @@
-From b302b7c9025334ef6680955a906cee579bf3c85c Mon Sep 17 00:00:00 2001
+From 89b466914a0d49f08d00be25556ba22497b9a284 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Sat, 17 Sep 2016 15:07:10 +0200
Subject: [PATCH] i2c: bcm2835: Fix hang for writing messages larger than 16
diff --git a/target/linux/brcm2708/patches-4.9/0108-i2c-bcm2835-Protect-against-unexpected-TXW-RXR-inter.patch b/target/linux/brcm2708/patches-4.9/0107-i2c-bcm2835-Protect-against-unexpected-TXW-RXR-inter.patch
index 0a616ff7ad..6646d77944 100644
--- a/target/linux/brcm2708/patches-4.9/0108-i2c-bcm2835-Protect-against-unexpected-TXW-RXR-inter.patch
+++ b/target/linux/brcm2708/patches-4.9/0107-i2c-bcm2835-Protect-against-unexpected-TXW-RXR-inter.patch
@@ -1,4 +1,4 @@
-From 95729fe299cca5ef749f4b6a2c3e0f40ec7b43b9 Mon Sep 17 00:00:00 2001
+From 8feb8081c74d15ce368baa42981ca98e77800c03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 23 Sep 2016 18:24:38 +0200
Subject: [PATCH] i2c: bcm2835: Protect against unexpected TXW/RXR interrupts
diff --git a/target/linux/brcm2708/patches-4.9/0109-i2c-bcm2835-Use-dev_dbg-logging-on-transfer-errors.patch b/target/linux/brcm2708/patches-4.9/0108-i2c-bcm2835-Use-dev_dbg-logging-on-transfer-errors.patch
index b8cbe10452..acc2ade0a3 100644
--- a/target/linux/brcm2708/patches-4.9/0109-i2c-bcm2835-Use-dev_dbg-logging-on-transfer-errors.patch
+++ b/target/linux/brcm2708/patches-4.9/0108-i2c-bcm2835-Use-dev_dbg-logging-on-transfer-errors.patch
@@ -1,4 +1,4 @@
-From 3e9e15ec9e56874764fdaa43b2af8008469b87b2 Mon Sep 17 00:00:00 2001
+From bff25210b88dc7b71ee9c2626e42a939072dec64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Mon, 19 Sep 2016 17:19:41 +0200
Subject: [PATCH] i2c: bcm2835: Use dev_dbg logging on transfer errors
diff --git a/target/linux/brcm2708/patches-4.9/0110-i2c-bcm2835-Can-t-support-I2C_M_IGNORE_NAK.patch b/target/linux/brcm2708/patches-4.9/0109-i2c-bcm2835-Can-t-support-I2C_M_IGNORE_NAK.patch
index 946c316bc1..a913c50082 100644
--- a/target/linux/brcm2708/patches-4.9/0110-i2c-bcm2835-Can-t-support-I2C_M_IGNORE_NAK.patch
+++ b/target/linux/brcm2708/patches-4.9/0109-i2c-bcm2835-Can-t-support-I2C_M_IGNORE_NAK.patch
@@ -1,4 +1,4 @@
-From 9d8c576116c4818dd745ff112504f0fdf78c9e1e Mon Sep 17 00:00:00 2001
+From 40c63177d4c0f4755a148503c3b8bb2192ce8c0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Thu, 22 Sep 2016 22:05:50 +0200
Subject: [PATCH] i2c: bcm2835: Can't support I2C_M_IGNORE_NAK
diff --git a/target/linux/brcm2708/patches-4.9/0111-i2c-bcm2835-Add-support-for-Repeated-Start-Condition.patch b/target/linux/brcm2708/patches-4.9/0110-i2c-bcm2835-Add-support-for-Repeated-Start-Condition.patch
index a481aaf235..0cd5aa4693 100644
--- a/target/linux/brcm2708/patches-4.9/0111-i2c-bcm2835-Add-support-for-Repeated-Start-Condition.patch
+++ b/target/linux/brcm2708/patches-4.9/0110-i2c-bcm2835-Add-support-for-Repeated-Start-Condition.patch
@@ -1,4 +1,4 @@
-From 1099ac9cbf927e62883b363cfe3d33db105ff3dc Mon Sep 17 00:00:00 2001
+From db656eb11aebb0d7e4b833f9b452503ddb1351f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 23 Sep 2016 04:54:27 +0200
Subject: [PATCH] i2c: bcm2835: Add support for Repeated Start Condition
diff --git a/target/linux/brcm2708/patches-4.9/0112-i2c-bcm2835-Support-i2c-dev-ioctl-I2C_TIMEOUT.patch b/target/linux/brcm2708/patches-4.9/0111-i2c-bcm2835-Support-i2c-dev-ioctl-I2C_TIMEOUT.patch
index ef70b978bf..07016d9782 100644
--- a/target/linux/brcm2708/patches-4.9/0112-i2c-bcm2835-Support-i2c-dev-ioctl-I2C_TIMEOUT.patch
+++ b/target/linux/brcm2708/patches-4.9/0111-i2c-bcm2835-Support-i2c-dev-ioctl-I2C_TIMEOUT.patch
@@ -1,4 +1,4 @@
-From d42e4206e0e273b195881614a317688830fc56a2 Mon Sep 17 00:00:00 2001
+From 0c2744e901150b27a60bded1acb058ce26709d5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Fri, 23 Sep 2016 04:57:17 +0200
Subject: [PATCH] i2c: bcm2835: Support i2c-dev ioctl I2C_TIMEOUT
diff --git a/target/linux/brcm2708/patches-4.9/0113-i2c-bcm2835-Add-support-for-dynamic-clock.patch b/target/linux/brcm2708/patches-4.9/0112-i2c-bcm2835-Add-support-for-dynamic-clock.patch
index 35ab56c510..afe2b2297c 100644
--- a/target/linux/brcm2708/patches-4.9/0113-i2c-bcm2835-Add-support-for-dynamic-clock.patch
+++ b/target/linux/brcm2708/patches-4.9/0112-i2c-bcm2835-Add-support-for-dynamic-clock.patch
@@ -1,4 +1,4 @@
-From 788daf43a9078fc592eddfa0b959bc92b03bbb53 Mon Sep 17 00:00:00 2001
+From ce8663f1f101f8c7b9037c31269b0b31373737ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Tue, 27 Sep 2016 01:00:08 +0200
Subject: [PATCH] i2c: bcm2835: Add support for dynamic clock
diff --git a/target/linux/brcm2708/patches-4.9/0114-i2c-bcm2835-Add-debug-support.patch b/target/linux/brcm2708/patches-4.9/0113-i2c-bcm2835-Add-debug-support.patch
index 30830672f9..f69a48f623 100644
--- a/target/linux/brcm2708/patches-4.9/0114-i2c-bcm2835-Add-debug-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0113-i2c-bcm2835-Add-debug-support.patch
@@ -1,4 +1,4 @@
-From 133b068ffc08e2c1a0c9d5fa781107e3d95ba9bc Mon Sep 17 00:00:00 2001
+From 98629f09f3ceb7f2a559b48b4a70028485583f5e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Tue, 1 Nov 2016 15:15:41 +0100
Subject: [PATCH] i2c: bcm2835: Add debug support
diff --git a/target/linux/brcm2708/patches-4.9/0115-arm64-Add-CONFIG_ARCH_BCM2835.patch b/target/linux/brcm2708/patches-4.9/0114-arm64-Add-CONFIG_ARCH_BCM2835.patch
index 2f84052eb0..34ab47e7b4 100644
--- a/target/linux/brcm2708/patches-4.9/0115-arm64-Add-CONFIG_ARCH_BCM2835.patch
+++ b/target/linux/brcm2708/patches-4.9/0114-arm64-Add-CONFIG_ARCH_BCM2835.patch
@@ -1,4 +1,4 @@
-From fbf6217ff64c7bf6fac6eafd07f23d8c2356b088 Mon Sep 17 00:00:00 2001
+From c3dc479ae9620756f981ad2c5afeee92295f8ea3 Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Sat, 31 Dec 2016 14:15:50 +0000
Subject: [PATCH] arm64: Add CONFIG_ARCH_BCM2835
diff --git a/target/linux/brcm2708/patches-4.9/0116-Add-support-for-Silicon-Labs-Si7013-20-21-humidity-t.patch b/target/linux/brcm2708/patches-4.9/0115-Add-support-for-Silicon-Labs-Si7013-20-21-humidity-t.patch
index 8ab820756e..119b054260 100644
--- a/target/linux/brcm2708/patches-4.9/0116-Add-support-for-Silicon-Labs-Si7013-20-21-humidity-t.patch
+++ b/target/linux/brcm2708/patches-4.9/0115-Add-support-for-Silicon-Labs-Si7013-20-21-humidity-t.patch
@@ -1,4 +1,4 @@
-From d7a7355799204dc94d323d8e58ff6d2d3296e764 Mon Sep 17 00:00:00 2001
+From 69d0de7d07ec016f2956237ec141bb62ff7ae36c Mon Sep 17 00:00:00 2001
From: Alex Tucker <alex@floop.org.uk>
Date: Tue, 13 Dec 2016 19:50:18 +0000
Subject: [PATCH] Add support for Silicon Labs Si7013/20/21
diff --git a/target/linux/brcm2708/patches-4.9/0117-Document-the-si7020-option.patch b/target/linux/brcm2708/patches-4.9/0116-Document-the-si7020-option.patch
index 67b72c9f3c..0319ca43a2 100644
--- a/target/linux/brcm2708/patches-4.9/0117-Document-the-si7020-option.patch
+++ b/target/linux/brcm2708/patches-4.9/0116-Document-the-si7020-option.patch
@@ -1,4 +1,4 @@
-From e6be13c337640f69fc71dcf6b6dd741dc5664f85 Mon Sep 17 00:00:00 2001
+From ed753b7389b8c65af0b4266c001ef0343fb1c30e Mon Sep 17 00:00:00 2001
From: Phil Elwell <pelwell@users.noreply.github.com>
Date: Tue, 3 Jan 2017 21:27:46 +0000
Subject: [PATCH] Document the si7020 option
diff --git a/target/linux/brcm2708/patches-4.9/0118-pisound-improvements.patch b/target/linux/brcm2708/patches-4.9/0117-pisound-improvements.patch
index af5c3b3fa6..f914bfc3ad 100644
--- a/target/linux/brcm2708/patches-4.9/0118-pisound-improvements.patch
+++ b/target/linux/brcm2708/patches-4.9/0117-pisound-improvements.patch
@@ -1,4 +1,4 @@
-From 811d783519254a955ccb7a43b1d8d3f2d29a9a79 Mon Sep 17 00:00:00 2001
+From 8ed8e29b19dba95a7a6c2364c2bb32d926601713 Mon Sep 17 00:00:00 2001
From: Giedrius Trainavicius <giedrius@blokas.io>
Date: Thu, 5 Jan 2017 02:38:16 +0200
Subject: [PATCH] pisound improvements:
diff --git a/target/linux/brcm2708/patches-4.9/0122-Add-driver_name-property.patch b/target/linux/brcm2708/patches-4.9/0118-Add-driver_name-property.patch
index 4acafa562c..bfda58aa5a 100644
--- a/target/linux/brcm2708/patches-4.9/0122-Add-driver_name-property.patch
+++ b/target/linux/brcm2708/patches-4.9/0118-Add-driver_name-property.patch
@@ -1,4 +1,4 @@
-From 6e7ad272d08767455aef658066b981f513ad0cec Mon Sep 17 00:00:00 2001
+From 341bc67d361def1f23a96c512ab6bc39f32b3601 Mon Sep 17 00:00:00 2001
From: Aaron Shaw <shawaj@gmail.com>
Date: Tue, 10 Jan 2017 16:05:41 +0000
Subject: [PATCH] Add driver_name property
diff --git a/target/linux/brcm2708/patches-4.9/0123-Add-driver_name-paramater.patch b/target/linux/brcm2708/patches-4.9/0119-Add-driver_name-paramater.patch
index c85bb445dc..2a3a6d8061 100644
--- a/target/linux/brcm2708/patches-4.9/0123-Add-driver_name-paramater.patch
+++ b/target/linux/brcm2708/patches-4.9/0119-Add-driver_name-paramater.patch
@@ -1,4 +1,4 @@
-From d9f58694b229b6f7e8b03c718ef80ac7082213d1 Mon Sep 17 00:00:00 2001
+From d87b665c7e4c09bf713ef6f45ceb11a8aacbcf5e Mon Sep 17 00:00:00 2001
From: Aaron Shaw <shawaj@gmail.com>
Date: Tue, 10 Jan 2017 16:11:04 +0000
Subject: [PATCH] Add driver_name paramater
diff --git a/target/linux/brcm2708/patches-4.9/0119-Revert-Revert-Added-driver-for-HiFiBerry-Amp-amplifi.patch b/target/linux/brcm2708/patches-4.9/0119-Revert-Revert-Added-driver-for-HiFiBerry-Amp-amplifi.patch
deleted file mode 100644
index d57bfe19ba..0000000000
--- a/target/linux/brcm2708/patches-4.9/0119-Revert-Revert-Added-driver-for-HiFiBerry-Amp-amplifi.patch
+++ /dev/null
@@ -1,809 +0,0 @@
-From 20779cac1f8632b2315e1421fdecc960dac7f1c3 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 9 Jan 2017 09:23:06 +0000
-Subject: [PATCH] Revert "Revert "Added driver for HiFiBerry Amp amplifier
- add-on board""
-
-This reverts commit bf84babd8fffcb79c60f1342c2416f8e1e4b7af9.
----
- sound/soc/bcm/Kconfig | 7 +
- sound/soc/bcm/Makefile | 2 +
- sound/soc/bcm/hifiberry_amp.c | 129 +++++++++++++++
- sound/soc/codecs/Kconfig | 4 +
- sound/soc/codecs/Makefile | 2 +
- sound/soc/codecs/tas5713.c | 369 ++++++++++++++++++++++++++++++++++++++++++
- sound/soc/codecs/tas5713.h | 210 ++++++++++++++++++++++++
- 7 files changed, 723 insertions(+)
- create mode 100644 sound/soc/bcm/hifiberry_amp.c
- create mode 100644 sound/soc/codecs/tas5713.c
- create mode 100644 sound/soc/codecs/tas5713.h
-
---- a/sound/soc/bcm/Kconfig
-+++ b/sound/soc/bcm/Kconfig
-@@ -38,6 +38,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DIGI
- help
- Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board.
-
-+config SND_BCM2708_SOC_HIFIBERRY_AMP
-+ tristate "Support for the HifiBerry Amp"
-+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
-+ select SND_SOC_TAS5713
-+ help
-+ Say Y or M if you want to add support for the HifiBerry Amp amplifier board.
-+
- config SND_BCM2708_SOC_RPI_DAC
- tristate "Support for RPi-DAC"
- depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
---- a/sound/soc/bcm/Makefile
-+++ b/sound/soc/bcm/Makefile
-@@ -10,6 +10,7 @@ obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-
-
- # BCM2708 Machine Support
- snd-soc-adau1977-adc-objs := adau1977-adc.o
-+snd-soc-hifiberry-amp-objs := hifiberry_amp.o
- snd-soc-hifiberry-dac-objs := hifiberry_dac.o
- snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o
- snd-soc-hifiberry-digi-objs := hifiberry_digi.o
-@@ -27,6 +28,7 @@ snd-soc-allo-piano-dac-objs := allo-pian
- snd-soc-pisound-objs := pisound.o
-
- obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
-+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o
- obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o
---- /dev/null
-+++ b/sound/soc/bcm/hifiberry_amp.c
-@@ -0,0 +1,129 @@
-+/*
-+ * ASoC Driver for HifiBerry AMP
-+ *
-+ * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
-+ * Copyright 2014
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+
-+#include <sound/core.h>
-+#include <sound/pcm.h>
-+#include <sound/pcm_params.h>
-+#include <sound/soc.h>
-+#include <sound/jack.h>
-+
-+static int snd_rpi_hifiberry_amp_init(struct snd_soc_pcm_runtime *rtd)
-+{
-+ // ToDo: init of the dsp-registers.
-+ return 0;
-+}
-+
-+static int snd_rpi_hifiberry_amp_hw_params( struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params )
-+{
-+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
-+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-+
-+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
-+}
-+
-+static struct snd_soc_ops snd_rpi_hifiberry_amp_ops = {
-+ .hw_params = snd_rpi_hifiberry_amp_hw_params,
-+};
-+
-+static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = {
-+ {
-+ .name = "HifiBerry AMP",
-+ .stream_name = "HifiBerry AMP HiFi",
-+ .cpu_dai_name = "bcm2708-i2s.0",
-+ .codec_dai_name = "tas5713-hifi",
-+ .platform_name = "bcm2708-i2s.0",
-+ .codec_name = "tas5713.1-001b",
-+ .dai_fmt = SND_SOC_DAIFMT_I2S |
-+ SND_SOC_DAIFMT_NB_NF |
-+ SND_SOC_DAIFMT_CBS_CFS,
-+ .ops = &snd_rpi_hifiberry_amp_ops,
-+ .init = snd_rpi_hifiberry_amp_init,
-+ },
-+};
-+
-+
-+static struct snd_soc_card snd_rpi_hifiberry_amp = {
-+ .name = "snd_rpi_hifiberry_amp",
-+ .driver_name = "HifiberryAmp",
-+ .owner = THIS_MODULE,
-+ .dai_link = snd_rpi_hifiberry_amp_dai,
-+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai),
-+};
-+
-+static const struct of_device_id snd_rpi_hifiberry_amp_of_match[] = {
-+ { .compatible = "hifiberry,hifiberry-amp", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_amp_of_match);
-+
-+
-+static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev)
-+{
-+ int ret = 0;
-+
-+ snd_rpi_hifiberry_amp.dev = &pdev->dev;
-+
-+ if (pdev->dev.of_node) {
-+ struct device_node *i2s_node;
-+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_amp_dai[0];
-+ i2s_node = of_parse_phandle(pdev->dev.of_node,
-+ "i2s-controller", 0);
-+
-+ if (i2s_node) {
-+ dai->cpu_dai_name = NULL;
-+ dai->cpu_of_node = i2s_node;
-+ dai->platform_name = NULL;
-+ dai->platform_of_node = i2s_node;
-+ }
-+ }
-+
-+ ret = snd_soc_register_card(&snd_rpi_hifiberry_amp);
-+
-+ if (ret != 0) {
-+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+static int snd_rpi_hifiberry_amp_remove(struct platform_device *pdev)
-+{
-+ return snd_soc_unregister_card(&snd_rpi_hifiberry_amp);
-+}
-+
-+
-+static struct platform_driver snd_rpi_hifiberry_amp_driver = {
-+ .driver = {
-+ .name = "snd-hifiberry-amp",
-+ .owner = THIS_MODULE,
-+ .of_match_table = snd_rpi_hifiberry_amp_of_match,
-+ },
-+ .probe = snd_rpi_hifiberry_amp_probe,
-+ .remove = snd_rpi_hifiberry_amp_remove,
-+};
-+
-+
-+module_platform_driver(snd_rpi_hifiberry_amp_driver);
-+
-+
-+MODULE_AUTHOR("Sebastian Eickhoff <basti.eickhoff@googlemail.com>");
-+MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP");
-+MODULE_LICENSE("GPL v2");
---- a/sound/soc/codecs/Kconfig
-+++ b/sound/soc/codecs/Kconfig
-@@ -139,6 +139,7 @@ config SND_SOC_ALL_CODECS
- select SND_SOC_TFA9879 if I2C
- select SND_SOC_TLV320AIC23_I2C if I2C
- select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
-+ select SND_SOC_TAS5713 if I2C
- select SND_SOC_TLV320AIC26 if SPI_MASTER
- select SND_SOC_TLV320AIC31XX if I2C
- select SND_SOC_TLV320AIC32X4_I2C if I2C
-@@ -821,6 +822,9 @@ config SND_SOC_TFA9879
- tristate "NXP Semiconductors TFA9879 amplifier"
- depends on I2C
-
-+config SND_SOC_TAS5713
-+ tristate
-+
- config SND_SOC_TLV320AIC23
- tristate
-
---- a/sound/soc/codecs/Makefile
-+++ b/sound/soc/codecs/Makefile
-@@ -144,6 +144,7 @@ snd-soc-tas5086-objs := tas5086.o
- snd-soc-tas571x-objs := tas571x.o
- snd-soc-tas5720-objs := tas5720.o
- snd-soc-tfa9879-objs := tfa9879.o
-+snd-soc-tas5713-objs := tas5713.o
- snd-soc-tlv320aic23-objs := tlv320aic23.o
- snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
- snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
-@@ -366,6 +367,7 @@ obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc
- obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
- obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
- obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o
-+obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o
- obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
- obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
- obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
---- /dev/null
-+++ b/sound/soc/codecs/tas5713.c
-@@ -0,0 +1,369 @@
-+/*
-+ * ASoC Driver for TAS5713
-+ *
-+ * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
-+ * Copyright 2014
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/i2c.h>
-+#include <linux/of_device.h>
-+#include <linux/spi/spi.h>
-+#include <linux/regmap.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/slab.h>
-+#include <sound/core.h>
-+#include <sound/pcm.h>
-+#include <sound/pcm_params.h>
-+#include <sound/soc.h>
-+#include <sound/initval.h>
-+#include <sound/tlv.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/fs.h>
-+#include <asm/uaccess.h>
-+
-+#include "tas5713.h"
-+
-+
-+static struct i2c_client *i2c;
-+
-+struct tas5713_priv {
-+ struct regmap *regmap;
-+ int mclk_div;
-+ struct snd_soc_codec *codec;
-+};
-+
-+static struct tas5713_priv *priv_data;
-+
-+
-+
-+
-+/*
-+ * _ _ ___ _ ___ _ _
-+ * /_\ | | / __| /_\ / __|___ _ _| |_ _ _ ___| |___
-+ * / _ \| |__\__ \/ _ \ | (__/ _ \ ' \ _| '_/ _ \ (_-<
-+ * /_/ \_\____|___/_/ \_\ \___\___/_||_\__|_| \___/_/__/
-+ *
-+ */
-+
-+static const DECLARE_TLV_DB_SCALE(tas5713_vol_tlv, -10000, 50, 1);
-+
-+
-+static const struct snd_kcontrol_new tas5713_snd_controls[] = {
-+ SOC_SINGLE_TLV ("Master" , TAS5713_VOL_MASTER, 0, 248, 1, tas5713_vol_tlv),
-+ SOC_DOUBLE_R_TLV("Channels" , TAS5713_VOL_CH1, TAS5713_VOL_CH2, 0, 248, 1, tas5713_vol_tlv)
-+};
-+
-+
-+
-+
-+/*
-+ * __ __ _ _ ___ _
-+ * | \/ |__ _ __| |_ (_)_ _ ___ | \ _ _(_)_ _____ _ _
-+ * | |\/| / _` / _| ' \| | ' \/ -_) | |) | '_| \ V / -_) '_|
-+ * |_| |_\__,_\__|_||_|_|_||_\___| |___/|_| |_|\_/\___|_|
-+ *
-+ */
-+
-+static int tas5713_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params,
-+ struct snd_soc_dai *dai)
-+{
-+ u16 blen = 0x00;
-+
-+ struct snd_soc_codec *codec;
-+ codec = dai->codec;
-+ priv_data->codec = dai->codec;
-+
-+ switch (params_format(params)) {
-+ case SNDRV_PCM_FORMAT_S16_LE:
-+ blen = 0x03;
-+ break;
-+ case SNDRV_PCM_FORMAT_S20_3LE:
-+ blen = 0x1;
-+ break;
-+ case SNDRV_PCM_FORMAT_S24_LE:
-+ blen = 0x04;
-+ break;
-+ case SNDRV_PCM_FORMAT_S32_LE:
-+ blen = 0x05;
-+ break;
-+ default:
-+ dev_err(dai->dev, "Unsupported word length: %u\n",
-+ params_format(params));
-+ return -EINVAL;
-+ }
-+
-+ // set word length
-+ snd_soc_update_bits(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x7, blen);
-+
-+ return 0;
-+}
-+
-+
-+static int tas5713_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
-+{
-+ unsigned int val = 0;
-+
-+ struct tas5713_priv *tas5713;
-+ struct snd_soc_codec *codec = dai->codec;
-+ tas5713 = snd_soc_codec_get_drvdata(codec);
-+
-+ if (mute) {
-+ val = TAS5713_SOFT_MUTE_ALL;
-+ }
-+
-+ return regmap_write(tas5713->regmap, TAS5713_SOFT_MUTE, val);
-+}
-+
-+
-+static const struct snd_soc_dai_ops tas5713_dai_ops = {
-+ .hw_params = tas5713_hw_params,
-+ .mute_stream = tas5713_mute_stream,
-+};
-+
-+
-+static struct snd_soc_dai_driver tas5713_dai = {
-+ .name = "tas5713-hifi",
-+ .playback = {
-+ .stream_name = "Playback",
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rates = SNDRV_PCM_RATE_8000_48000,
-+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE ),
-+ },
-+ .ops = &tas5713_dai_ops,
-+};
-+
-+
-+
-+
-+/*
-+ * ___ _ ___ _
-+ * / __|___ __| |___ __ | \ _ _(_)_ _____ _ _
-+ * | (__/ _ \/ _` / -_) _| | |) | '_| \ V / -_) '_|
-+ * \___\___/\__,_\___\__| |___/|_| |_|\_/\___|_|
-+ *
-+ */
-+
-+static int tas5713_remove(struct snd_soc_codec *codec)
-+{
-+ struct tas5713_priv *tas5713;
-+
-+ tas5713 = snd_soc_codec_get_drvdata(codec);
-+
-+ return 0;
-+}
-+
-+
-+static int tas5713_probe(struct snd_soc_codec *codec)
-+{
-+ struct tas5713_priv *tas5713;
-+ int i, ret;
-+
-+ i2c = container_of(codec->dev, struct i2c_client, dev);
-+
-+ tas5713 = snd_soc_codec_get_drvdata(codec);
-+
-+ // Reset error
-+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
-+ if (ret < 0) return ret;
-+
-+ // Trim oscillator
-+ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00);
-+ if (ret < 0) return ret;
-+ msleep(1000);
-+
-+ // Reset error
-+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00);
-+ if (ret < 0) return ret;
-+
-+ // Clock mode: 44/48kHz, MCLK=64xfs
-+ ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60);
-+ if (ret < 0) return ret;
-+
-+ // I2S 24bit
-+ ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05);
-+ if (ret < 0) return ret;
-+
-+ // Unmute
-+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
-+ if (ret < 0) return ret;
-+ ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00);
-+ if (ret < 0) return ret;
-+
-+ // Set volume to 0db
-+ ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00);
-+ if (ret < 0) return ret;
-+
-+ // Now start programming the default initialization sequence
-+ for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) {
-+ ret = i2c_master_send(i2c,
-+ tas5713_init_sequence[i].data,
-+ tas5713_init_sequence[i].size);
-+ if (ret < 0) {
-+ printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret);
-+ }
-+ }
-+
-+ // Unmute
-+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00);
-+ if (ret < 0) return ret;
-+
-+ return 0;
-+}
-+
-+
-+static struct snd_soc_codec_driver soc_codec_dev_tas5713 = {
-+ .probe = tas5713_probe,
-+ .remove = tas5713_remove,
-+ .controls = tas5713_snd_controls,
-+ .num_controls = ARRAY_SIZE(tas5713_snd_controls),
-+};
-+
-+
-+
-+
-+/*
-+ * ___ ___ ___ ___ _
-+ * |_ _|_ ) __| | \ _ _(_)_ _____ _ _
-+ * | | / / (__ | |) | '_| \ V / -_) '_|
-+ * |___/___\___| |___/|_| |_|\_/\___|_|
-+ *
-+ */
-+
-+static const struct reg_default tas5713_reg_defaults[] = {
-+ { 0x07 ,0x80 }, // R7 - VOL_MASTER - -40dB
-+ { 0x08 , 30 }, // R8 - VOL_CH1 - 0dB
-+ { 0x09 , 30 }, // R9 - VOL_CH2 - 0dB
-+ { 0x0A ,0x80 }, // R10 - VOL_HEADPHONE - -40dB
-+};
-+
-+
-+static bool tas5713_reg_volatile(struct device *dev, unsigned int reg)
-+{
-+ switch (reg) {
-+ case TAS5713_DEVICE_ID:
-+ case TAS5713_ERROR_STATUS:
-+ return true;
-+ default:
-+ return false;
-+ }
-+}
-+
-+
-+static const struct of_device_id tas5713_of_match[] = {
-+ { .compatible = "ti,tas5713", },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, tas5713_of_match);
-+
-+
-+static struct regmap_config tas5713_regmap_config = {
-+ .reg_bits = 8,
-+ .val_bits = 8,
-+
-+ .max_register = TAS5713_MAX_REGISTER,
-+ .volatile_reg = tas5713_reg_volatile,
-+
-+ .cache_type = REGCACHE_RBTREE,
-+ .reg_defaults = tas5713_reg_defaults,
-+ .num_reg_defaults = ARRAY_SIZE(tas5713_reg_defaults),
-+};
-+
-+
-+static int tas5713_i2c_probe(struct i2c_client *i2c,
-+ const struct i2c_device_id *id)
-+{
-+ int ret;
-+
-+ priv_data = devm_kzalloc(&i2c->dev, sizeof *priv_data, GFP_KERNEL);
-+ if (!priv_data)
-+ return -ENOMEM;
-+
-+ priv_data->regmap = devm_regmap_init_i2c(i2c, &tas5713_regmap_config);
-+ if (IS_ERR(priv_data->regmap)) {
-+ ret = PTR_ERR(priv_data->regmap);
-+ return ret;
-+ }
-+
-+ i2c_set_clientdata(i2c, priv_data);
-+
-+ ret = snd_soc_register_codec(&i2c->dev,
-+ &soc_codec_dev_tas5713, &tas5713_dai, 1);
-+
-+ return ret;
-+}
-+
-+
-+static int tas5713_i2c_remove(struct i2c_client *i2c)
-+{
-+ snd_soc_unregister_codec(&i2c->dev);
-+ i2c_set_clientdata(i2c, NULL);
-+
-+ kfree(priv_data);
-+
-+ return 0;
-+}
-+
-+
-+static const struct i2c_device_id tas5713_i2c_id[] = {
-+ { "tas5713", 0 },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(i2c, tas5713_i2c_id);
-+
-+
-+static struct i2c_driver tas5713_i2c_driver = {
-+ .driver = {
-+ .name = "tas5713",
-+ .owner = THIS_MODULE,
-+ .of_match_table = tas5713_of_match,
-+ },
-+ .probe = tas5713_i2c_probe,
-+ .remove = tas5713_i2c_remove,
-+ .id_table = tas5713_i2c_id
-+};
-+
-+
-+static int __init tas5713_modinit(void)
-+{
-+ int ret = 0;
-+
-+ ret = i2c_add_driver(&tas5713_i2c_driver);
-+ if (ret) {
-+ printk(KERN_ERR "Failed to register tas5713 I2C driver: %d\n",
-+ ret);
-+ }
-+
-+ return ret;
-+}
-+module_init(tas5713_modinit);
-+
-+
-+static void __exit tas5713_exit(void)
-+{
-+ i2c_del_driver(&tas5713_i2c_driver);
-+}
-+module_exit(tas5713_exit);
-+
-+
-+MODULE_AUTHOR("Sebastian Eickhoff <basti.eickhoff@googlemail.com>");
-+MODULE_DESCRIPTION("ASoC driver for TAS5713");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/sound/soc/codecs/tas5713.h
-@@ -0,0 +1,210 @@
-+/*
-+ * ASoC Driver for TAS5713
-+ *
-+ * Author: Sebastian Eickhoff <basti.eickhoff@googlemail.com>
-+ * Copyright 2014
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ */
-+
-+#ifndef _TAS5713_H
-+#define _TAS5713_H
-+
-+
-+// TAS5713 I2C-bus register addresses
-+
-+#define TAS5713_CLOCK_CTRL 0x00
-+#define TAS5713_DEVICE_ID 0x01
-+#define TAS5713_ERROR_STATUS 0x02
-+#define TAS5713_SYSTEM_CTRL1 0x03
-+#define TAS5713_SERIAL_DATA_INTERFACE 0x04
-+#define TAS5713_SYSTEM_CTRL2 0x05
-+#define TAS5713_SOFT_MUTE 0x06
-+#define TAS5713_VOL_MASTER 0x07
-+#define TAS5713_VOL_CH1 0x08
-+#define TAS5713_VOL_CH2 0x09
-+#define TAS5713_VOL_HEADPHONE 0x0A
-+#define TAS5713_VOL_CONFIG 0x0E
-+#define TAS5713_MODULATION_LIMIT 0x10
-+#define TAS5713_IC_DLY_CH1 0x11
-+#define TAS5713_IC_DLY_CH2 0x12
-+#define TAS5713_IC_DLY_CH3 0x13
-+#define TAS5713_IC_DLY_CH4 0x14
-+
-+#define TAS5713_START_STOP_PERIOD 0x1A
-+#define TAS5713_OSC_TRIM 0x1B
-+#define TAS5713_BKND_ERR 0x1C
-+
-+#define TAS5713_INPUT_MUX 0x20
-+#define TAS5713_SRC_SELECT_CH4 0x21
-+#define TAS5713_PWM_MUX 0x25
-+
-+#define TAS5713_CH1_BQ0 0x29
-+#define TAS5713_CH1_BQ1 0x2A
-+#define TAS5713_CH1_BQ2 0x2B
-+#define TAS5713_CH1_BQ3 0x2C
-+#define TAS5713_CH1_BQ4 0x2D
-+#define TAS5713_CH1_BQ5 0x2E
-+#define TAS5713_CH1_BQ6 0x2F
-+#define TAS5713_CH1_BQ7 0x58
-+#define TAS5713_CH1_BQ8 0x59
-+
-+#define TAS5713_CH2_BQ0 0x30
-+#define TAS5713_CH2_BQ1 0x31
-+#define TAS5713_CH2_BQ2 0x32
-+#define TAS5713_CH2_BQ3 0x33
-+#define TAS5713_CH2_BQ4 0x34
-+#define TAS5713_CH2_BQ5 0x35
-+#define TAS5713_CH2_BQ6 0x36
-+#define TAS5713_CH2_BQ7 0x5C
-+#define TAS5713_CH2_BQ8 0x5D
-+
-+#define TAS5713_CH4_BQ0 0x5A
-+#define TAS5713_CH4_BQ1 0x5B
-+#define TAS5713_CH3_BQ0 0x5E
-+#define TAS5713_CH3_BQ1 0x5F
-+
-+#define TAS5713_DRC1_SOFTENING_FILTER_ALPHA_OMEGA 0x3B
-+#define TAS5713_DRC1_ATTACK_RELEASE_RATE 0x3C
-+#define TAS5713_DRC2_SOFTENING_FILTER_ALPHA_OMEGA 0x3E
-+#define TAS5713_DRC2_ATTACK_RELEASE_RATE 0x3F
-+#define TAS5713_DRC1_ATTACK_RELEASE_THRES 0x40
-+#define TAS5713_DRC2_ATTACK_RELEASE_THRES 0x43
-+#define TAS5713_DRC_CTRL 0x46
-+
-+#define TAS5713_BANK_SW_CTRL 0x50
-+#define TAS5713_CH1_OUTPUT_MIXER 0x51
-+#define TAS5713_CH2_OUTPUT_MIXER 0x52
-+#define TAS5713_CH1_INPUT_MIXER 0x53
-+#define TAS5713_CH2_INPUT_MIXER 0x54
-+#define TAS5713_OUTPUT_POST_SCALE 0x56
-+#define TAS5713_OUTPUT_PRESCALE 0x57
-+
-+#define TAS5713_IDF_POST_SCALE 0x62
-+
-+#define TAS5713_CH1_INLINE_MIXER 0x70
-+#define TAS5713_CH1_INLINE_DRC_EN_MIXER 0x71
-+#define TAS5713_CH1_R_CHANNEL_MIXER 0x72
-+#define TAS5713_CH1_L_CHANNEL_MIXER 0x73
-+#define TAS5713_CH2_INLINE_MIXER 0x74
-+#define TAS5713_CH2_INLINE_DRC_EN_MIXER 0x75
-+#define TAS5713_CH2_L_CHANNEL_MIXER 0x76
-+#define TAS5713_CH2_R_CHANNEL_MIXER 0x77
-+
-+#define TAS5713_UPDATE_DEV_ADDR_KEY 0xF8
-+#define TAS5713_UPDATE_DEV_ADDR_REG 0xF9
-+
-+#define TAS5713_REGISTER_COUNT 0x46
-+#define TAS5713_MAX_REGISTER 0xF9
-+
-+
-+// Bitmasks for registers
-+#define TAS5713_SOFT_MUTE_ALL 0x07
-+
-+
-+
-+struct tas5713_init_command {
-+ const int size;
-+ const char *const data;
-+};
-+
-+static const struct tas5713_init_command tas5713_init_sequence[] = {
-+
-+ // Trim oscillator
-+ { .size = 2, .data = "\x1B\x00" },
-+ // System control register 1 (0x03): block DC
-+ { .size = 2, .data = "\x03\x80" },
-+ // Mute everything
-+ { .size = 2, .data = "\x05\x40" },
-+ // Modulation limit register (0x10): 97.7%
-+ { .size = 2, .data = "\x10\x02" },
-+ // Interchannel delay registers
-+ // (0x11, 0x12, 0x13, and 0x14): BD mode
-+ { .size = 2, .data = "\x11\xB8" },
-+ { .size = 2, .data = "\x12\x60" },
-+ { .size = 2, .data = "\x13\xA0" },
-+ { .size = 2, .data = "\x14\x48" },
-+ // PWM shutdown group register (0x19): no shutdown
-+ { .size = 2, .data = "\x19\x00" },
-+ // Input multiplexer register (0x20): BD mode
-+ { .size = 2, .data = "\x20\x00\x89\x77\x72" },
-+ // PWM output mux register (0x25)
-+ // Channel 1 --> OUTA, channel 1 neg --> OUTB
-+ // Channel 2 --> OUTC, channel 2 neg --> OUTD
-+ { .size = 5, .data = "\x25\x01\x02\x13\x45" },
-+ // DRC control (0x46): DRC off
-+ { .size = 5, .data = "\x46\x00\x00\x00\x00" },
-+ // BKND_ERR register (0x1C): 299ms reset period
-+ { .size = 2, .data = "\x1C\x07" },
-+ // Mute channel 3
-+ { .size = 2, .data = "\x0A\xFF" },
-+ // Volume configuration register (0x0E): volume slew 512 steps
-+ { .size = 2, .data = "\x0E\x90" },
-+ // Clock control register (0x00): 44/48kHz, MCLK=64xfs
-+ { .size = 2, .data = "\x00\x60" },
-+ // Bank switch and eq control (0x50): no bank switching
-+ { .size = 5, .data = "\x50\x00\x00\x00\x00" },
-+ // Volume registers (0x07, 0x08, 0x09, 0x0A)
-+ { .size = 2, .data = "\x07\x20" },
-+ { .size = 2, .data = "\x08\x30" },
-+ { .size = 2, .data = "\x09\x30" },
-+ { .size = 2, .data = "\x0A\xFF" },
-+ // 0x72, 0x73, 0x76, 0x77 input mixer:
-+ // no intermix between channels
-+ { .size = 5, .data = "\x72\x00\x00\x00\x00" },
-+ { .size = 5, .data = "\x73\x00\x80\x00\x00" },
-+ { .size = 5, .data = "\x76\x00\x00\x00\x00" },
-+ { .size = 5, .data = "\x77\x00\x80\x00\x00" },
-+ // 0x70, 0x71, 0x74, 0x75 inline DRC mixer:
-+ // no inline DRC inmix
-+ { .size = 5, .data = "\x70\x00\x80\x00\x00" },
-+ { .size = 5, .data = "\x71\x00\x00\x00\x00" },
-+ { .size = 5, .data = "\x74\x00\x80\x00\x00" },
-+ { .size = 5, .data = "\x75\x00\x00\x00\x00" },
-+ // 0x56, 0x57 Output scale
-+ { .size = 5, .data = "\x56\x00\x80\x00\x00" },
-+ { .size = 5, .data = "\x57\x00\x02\x00\x00" },
-+ // 0x3B, 0x3c
-+ { .size = 9, .data = "\x3B\x00\x08\x00\x00\x00\x78\x00\x00" },
-+ { .size = 9, .data = "\x3C\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-+ { .size = 9, .data = "\x3E\x00\x08\x00\x00\x00\x78\x00\x00" },
-+ { .size = 9, .data = "\x3F\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-+ { .size = 9, .data = "\x40\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-+ { .size = 9, .data = "\x43\x00\x00\x01\x00\xFF\xFF\xFF\x00" },
-+ // 0x51, 0x52: output mixer
-+ { .size = 9, .data = "\x51\x00\x80\x00\x00\x00\x00\x00\x00" },
-+ { .size = 9, .data = "\x52\x00\x80\x00\x00\x00\x00\x00\x00" },
-+ // PEQ defaults
-+ { .size = 21, .data = "\x29\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x2A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x2B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x2C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x2D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x2E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x2F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x30\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x31\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x32\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x33\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x34\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x35\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x36\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x58\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x59\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x5C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x5D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x5E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x5F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x5A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+ { .size = 21, .data = "\x5B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" },
-+};
-+
-+
-+#endif /* _TAS5713_H */
diff --git a/target/linux/brcm2708/patches-4.9/0124-BCM270X_DT-Add-pi3-disable-wifi-overlay.patch b/target/linux/brcm2708/patches-4.9/0120-BCM270X_DT-Add-pi3-disable-wifi-overlay.patch
index 473876bf98..4bc80bef04 100644
--- a/target/linux/brcm2708/patches-4.9/0124-BCM270X_DT-Add-pi3-disable-wifi-overlay.patch
+++ b/target/linux/brcm2708/patches-4.9/0120-BCM270X_DT-Add-pi3-disable-wifi-overlay.patch
@@ -1,4 +1,4 @@
-From 11e7774ca60d3e6e9063ecfb497f15aa808f7ca2 Mon Sep 17 00:00:00 2001
+From b76839857c9b553f52f8d14cf54a22579b362db9 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 11 Jan 2017 13:01:21 +0000
Subject: [PATCH] BCM270X_DT: Add pi3-disable-wifi overlay
diff --git a/target/linux/brcm2708/patches-4.9/0120-hifiberry-amp-Adjust-for-ALSA-object-refactoring.patch b/target/linux/brcm2708/patches-4.9/0120-hifiberry-amp-Adjust-for-ALSA-object-refactoring.patch
deleted file mode 100644
index 0de8da03e6..0000000000
--- a/target/linux/brcm2708/patches-4.9/0120-hifiberry-amp-Adjust-for-ALSA-object-refactoring.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 5f73a356386a40f331c86a68e2dad1dd0a4bbcd8 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 9 Jan 2017 09:42:09 +0000
-Subject: [PATCH] hifiberry-amp: Adjust for ALSA object refactoring
-
-See: https://github.com/raspberrypi/linux/issues/1775
----
- sound/soc/codecs/tas5713.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/sound/soc/codecs/tas5713.c
-+++ b/sound/soc/codecs/tas5713.c
-@@ -232,8 +232,10 @@ static int tas5713_probe(struct snd_soc_
- static struct snd_soc_codec_driver soc_codec_dev_tas5713 = {
- .probe = tas5713_probe,
- .remove = tas5713_remove,
-- .controls = tas5713_snd_controls,
-- .num_controls = ARRAY_SIZE(tas5713_snd_controls),
-+ .component_driver = {
-+ .controls = tas5713_snd_controls,
-+ .num_controls = ARRAY_SIZE(tas5713_snd_controls),
-+ },
- };
-
-
diff --git a/target/linux/brcm2708/patches-4.9/0125-ARM64-Make-it-work-again-on-4.9-1790.patch b/target/linux/brcm2708/patches-4.9/0121-ARM64-Make-it-work-again-on-4.9-1790.patch
index a60080cb27..96b298dd1b 100644
--- a/target/linux/brcm2708/patches-4.9/0125-ARM64-Make-it-work-again-on-4.9-1790.patch
+++ b/target/linux/brcm2708/patches-4.9/0121-ARM64-Make-it-work-again-on-4.9-1790.patch
@@ -1,4 +1,4 @@
-From d6fbb7bbbe2fcc6b348ba0cfc3523d7f8f18a619 Mon Sep 17 00:00:00 2001
+From fe3c34c6196cfc708a515e44dd432da0e6cc0aba Mon Sep 17 00:00:00 2001
From: Electron752 <mzoran@crowfest.net>
Date: Thu, 12 Jan 2017 07:07:08 -0800
Subject: [PATCH] ARM64: Make it work again on 4.9 (#1790)
diff --git a/target/linux/brcm2708/patches-4.9/0121-bcm2835-i2s-Changes-for-allowing-asymmetric-sample-f.patch b/target/linux/brcm2708/patches-4.9/0121-bcm2835-i2s-Changes-for-allowing-asymmetric-sample-f.patch
deleted file mode 100644
index 0cc0f8848d..0000000000
--- a/target/linux/brcm2708/patches-4.9/0121-bcm2835-i2s-Changes-for-allowing-asymmetric-sample-f.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From 425ee76116894c97d5d97ad4883eb2612b8692f3 Mon Sep 17 00:00:00 2001
-From: Giedrius Trainavicius <giedrius@blokas.io>
-Date: Sun, 8 Jan 2017 15:58:54 +0200
-Subject: [PATCH] bcm2835-i2s: Changes for allowing asymmetric sample formats.
-
-This is achieved by making changes only to the requested
-stream direction format, keeping the other stream direction
-configuration intact.
-
-Signed-off-by: Giedrius Trainavicius <giedrius@blokas.io>
----
- sound/soc/bcm/bcm2835-i2s.c | 54 +++++++++++++++++++++++++++++++--------------
- 1 file changed, 38 insertions(+), 16 deletions(-)
-
---- a/sound/soc/bcm/bcm2835-i2s.c
-+++ b/sound/soc/bcm/bcm2835-i2s.c
-@@ -237,7 +237,9 @@ static int bcm2835_i2s_hw_params(struct
- unsigned int sampling_rate = params_rate(params);
- unsigned int data_length, data_delay, bclk_ratio;
- unsigned int ch1pos, ch2pos, mode, format;
-+ unsigned int previous_ftxp, previous_frxp;
- uint32_t csreg;
-+ bool packed;
-
- /*
- * If a stream is already enabled,
-@@ -320,26 +322,46 @@ static int bcm2835_i2s_hw_params(struct
- return -EINVAL;
- }
-
-- /*
-- * Set format for both streams.
-- * We cannot set another frame length
-- * (and therefore word length) anyway,
-- * so the format will be the same.
-- */
-- regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format);
-- regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format);
-+ /* Set the format for the matching stream direction. */
-+ switch (substream->stream) {
-+ case SNDRV_PCM_STREAM_PLAYBACK:
-+ regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format);
-+ break;
-+ case SNDRV_PCM_STREAM_CAPTURE:
-+ regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-
- /* Setup the I2S mode */
-+ /* Keep existing FTXP and FRXP values. */
-+ regmap_read(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, &mode);
-+
-+ previous_ftxp = mode & BCM2835_I2S_FTXP;
-+ previous_frxp = mode & BCM2835_I2S_FRXP;
-+
- mode = 0;
-
-- if (data_length <= 16) {
-- /*
-- * Use frame packed mode (2 channels per 32 bit word)
-- * We cannot set another frame length in the second stream
-- * (and therefore word length) anyway,
-- * so the format will be the same.
-- */
-- mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP;
-+ /*
-+ * Retain the frame packed mode (2 channels per 32 bit word)
-+ * of the other direction stream intact. The formats of each
-+ * direction can be different as long as the frame length is
-+ * shared for both.
-+ */
-+ packed = data_length <= 16;
-+
-+ switch (substream->stream) {
-+ case SNDRV_PCM_STREAM_PLAYBACK:
-+ mode |= previous_frxp;
-+ mode |= packed ? BCM2835_I2S_FTXP : 0;
-+ break;
-+ case SNDRV_PCM_STREAM_CAPTURE:
-+ mode |= previous_ftxp;
-+ mode |= packed ? BCM2835_I2S_FRXP : 0;
-+ break;
-+ default:
-+ return -EINVAL;
- }
-
- mode |= BCM2835_I2S_FLEN(bclk_ratio - 1);
diff --git a/target/linux/brcm2708/patches-4.9/0126-ARM64-Enable-Kernel-Address-Space-Randomization-1792.patch b/target/linux/brcm2708/patches-4.9/0122-ARM64-Enable-Kernel-Address-Space-Randomization-1792.patch
index dff27b9ef0..423db95e9e 100644
--- a/target/linux/brcm2708/patches-4.9/0126-ARM64-Enable-Kernel-Address-Space-Randomization-1792.patch
+++ b/target/linux/brcm2708/patches-4.9/0122-ARM64-Enable-Kernel-Address-Space-Randomization-1792.patch
@@ -1,4 +1,4 @@
-From 8930b9b96484e1fd68438c78e44b8ef7cb2d61ac Mon Sep 17 00:00:00 2001
+From 6dfa60daaa0966a8e414ab0a7fd002a99001920a Mon Sep 17 00:00:00 2001
From: Electron752 <mzoran@crowfest.net>
Date: Sat, 14 Jan 2017 02:54:26 -0800
Subject: [PATCH] ARM64: Enable Kernel Address Space Randomization (#1792)
diff --git a/target/linux/brcm2708/patches-4.9/0128-ARM64-Enable-RTL8187-RTL8192CU-wifi-in-build-config.patch b/target/linux/brcm2708/patches-4.9/0124-ARM64-Enable-RTL8187-RTL8192CU-wifi-in-build-config.patch
index a309394994..c947a74c5d 100644
--- a/target/linux/brcm2708/patches-4.9/0128-ARM64-Enable-RTL8187-RTL8192CU-wifi-in-build-config.patch
+++ b/target/linux/brcm2708/patches-4.9/0124-ARM64-Enable-RTL8187-RTL8192CU-wifi-in-build-config.patch
@@ -1,4 +1,4 @@
-From 0d1eefab92dbaca44fa241df4bbf234212782d43 Mon Sep 17 00:00:00 2001
+From 564df2de35a212639eb7e357442f35fa89bcbde4 Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran@crowfest.net>
Date: Sun, 15 Jan 2017 07:31:59 -0800
Subject: [PATCH] ARM64: Enable RTL8187/RTL8192CU wifi in build config
diff --git a/target/linux/brcm2708/patches-4.9/0129-BCM270X_DT-Add-spi0-cs-overlay.patch b/target/linux/brcm2708/patches-4.9/0125-BCM270X_DT-Add-spi0-cs-overlay.patch
index e90767a95a..2fd8366f4e 100644
--- a/target/linux/brcm2708/patches-4.9/0129-BCM270X_DT-Add-spi0-cs-overlay.patch
+++ b/target/linux/brcm2708/patches-4.9/0125-BCM270X_DT-Add-spi0-cs-overlay.patch
@@ -1,4 +1,4 @@
-From efdb964748f093780166ef56fa7873067d35074e Mon Sep 17 00:00:00 2001
+From 48eea36959fb8d854b4cf1ee4284646be5a279e0 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 16 Jan 2017 14:53:12 +0000
Subject: [PATCH] BCM270X_DT: Add spi0-cs overlay
diff --git a/target/linux/brcm2708/patches-4.9/0130-spi-bcm2835-Disable-forced-software-CS.patch b/target/linux/brcm2708/patches-4.9/0126-spi-bcm2835-Disable-forced-software-CS.patch
index b4ade04396..544ccf6f0b 100644
--- a/target/linux/brcm2708/patches-4.9/0130-spi-bcm2835-Disable-forced-software-CS.patch
+++ b/target/linux/brcm2708/patches-4.9/0126-spi-bcm2835-Disable-forced-software-CS.patch
@@ -1,4 +1,4 @@
-From 2248b18b5d21d0ce59bb874a8e20e53a39317eb0 Mon Sep 17 00:00:00 2001
+From a6ef8db0e46713da43c81bc15fed01a4da0bd5a4 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Fri, 1 Jul 2016 22:09:24 +0100
Subject: [PATCH] spi-bcm2835: Disable forced software CS
diff --git a/target/linux/brcm2708/patches-4.9/0131-config-Add-CONFIG_TCP_CONG_BBR.patch b/target/linux/brcm2708/patches-4.9/0127-config-Add-CONFIG_TCP_CONG_BBR.patch
index f0076ce5ee..cec560e06e 100644
--- a/target/linux/brcm2708/patches-4.9/0131-config-Add-CONFIG_TCP_CONG_BBR.patch
+++ b/target/linux/brcm2708/patches-4.9/0127-config-Add-CONFIG_TCP_CONG_BBR.patch
@@ -1,4 +1,4 @@
-From 7342a6ab0f9d60cc65a2a585ac43d3aa114f7e61 Mon Sep 17 00:00:00 2001
+From 6f95da255ded5f1da673f826de07963e6a619e3d Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Mon, 16 Jan 2017 16:33:54 +0000
Subject: [PATCH] config: Add CONFIG_TCP_CONG_BBR See:
diff --git a/target/linux/brcm2708/patches-4.9/0133-BCM270X_DT-Enable-UART0-on-CM3.patch b/target/linux/brcm2708/patches-4.9/0128-BCM270X_DT-Enable-UART0-on-CM3.patch
index c2ba65f9a9..4fbc443dcd 100644
--- a/target/linux/brcm2708/patches-4.9/0133-BCM270X_DT-Enable-UART0-on-CM3.patch
+++ b/target/linux/brcm2708/patches-4.9/0128-BCM270X_DT-Enable-UART0-on-CM3.patch
@@ -1,4 +1,4 @@
-From 074d3a044fc1d3bc54c3728ae4ae045ef432a1d2 Mon Sep 17 00:00:00 2001
+From 44586947e86f67ad71fdd3afca51f04fc27f3872 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 17 Jan 2017 11:34:58 +0000
Subject: [PATCH] BCM270X_DT: Enable UART0 on CM3
diff --git a/target/linux/brcm2708/patches-4.9/0134-config-Add-CONFIG_MD_M25P80-and-CONFIG_MD_SPI_NOR.patch b/target/linux/brcm2708/patches-4.9/0129-config-Add-CONFIG_MD_M25P80-and-CONFIG_MD_SPI_NOR.patch
index 3d1bb7e0d0..ab5e409006 100644
--- a/target/linux/brcm2708/patches-4.9/0134-config-Add-CONFIG_MD_M25P80-and-CONFIG_MD_SPI_NOR.patch
+++ b/target/linux/brcm2708/patches-4.9/0129-config-Add-CONFIG_MD_M25P80-and-CONFIG_MD_SPI_NOR.patch
@@ -1,4 +1,4 @@
-From 1159cc636986b9915419efa87e136279b4ba7df9 Mon Sep 17 00:00:00 2001
+From 3f6ad80c79570b157d651720bf161843a360e922 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Tue, 17 Jan 2017 14:39:39 +0000
Subject: [PATCH] config: Add CONFIG_MD_M25P80 and CONFIG_MD_SPI_NOR
diff --git a/target/linux/brcm2708/patches-4.9/0135-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch b/target/linux/brcm2708/patches-4.9/0130-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch
index 4bb85d01c2..a94fee4690 100644
--- a/target/linux/brcm2708/patches-4.9/0135-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch
+++ b/target/linux/brcm2708/patches-4.9/0130-ARM64-DWC_OTG-Port-dwc_otg-driver-to-ARM64.patch
@@ -1,4 +1,4 @@
-From 2f15deb5ab0fafa71f00bcf840cd01893b829555 Mon Sep 17 00:00:00 2001
+From 99c33b6e418cefebb461fee0ad3a927a0c4127f1 Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran@crowfest.net>
Date: Sat, 14 Jan 2017 21:33:51 -0800
Subject: [PATCH] ARM64/DWC_OTG: Port dwc_otg driver to ARM64
diff --git a/target/linux/brcm2708/patches-4.9/0136-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch b/target/linux/brcm2708/patches-4.9/0131-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch
index 6685bbb7c1..d11ca6bffd 100644
--- a/target/linux/brcm2708/patches-4.9/0136-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch
+++ b/target/linux/brcm2708/patches-4.9/0131-ARM64-Round-Robin-dispatch-IRQs-between-CPUs.patch
@@ -1,4 +1,4 @@
-From b51f35c59a6f40f7f58ff75a2c1b414421224ec2 Mon Sep 17 00:00:00 2001
+From 3a9b48156c6681e846d1a7dbe4ecbb3ae14c2f3c Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran@crowfest.net>
Date: Sat, 14 Jan 2017 21:43:57 -0800
Subject: [PATCH] ARM64: Round-Robin dispatch IRQs between CPUs.
diff --git a/target/linux/brcm2708/patches-4.9/0137-ARM64-Enable-DWC_OTG-Driver-In-ARM64-Build-Config-bc.patch b/target/linux/brcm2708/patches-4.9/0132-ARM64-Enable-DWC_OTG-Driver-In-ARM64-Build-Config-bc.patch
index 4850c3ed87..deae274af3 100644
--- a/target/linux/brcm2708/patches-4.9/0137-ARM64-Enable-DWC_OTG-Driver-In-ARM64-Build-Config-bc.patch
+++ b/target/linux/brcm2708/patches-4.9/0132-ARM64-Enable-DWC_OTG-Driver-In-ARM64-Build-Config-bc.patch
@@ -1,4 +1,4 @@
-From b0a66d71d5efa5ab172a2e561ef76f510f80b305 Mon Sep 17 00:00:00 2001
+From ad17c9e5a03f835605560e7163e5e685a67abd1f Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran@crowfest.net>
Date: Sat, 14 Jan 2017 21:45:03 -0800
Subject: [PATCH] ARM64: Enable DWC_OTG Driver In ARM64 Build
diff --git a/target/linux/brcm2708/patches-4.9/0132-Revert-bcm2835-i2s-Changes-for-allowing-asymmetric-s.patch b/target/linux/brcm2708/patches-4.9/0132-Revert-bcm2835-i2s-Changes-for-allowing-asymmetric-s.patch
deleted file mode 100644
index 189b288898..0000000000
--- a/target/linux/brcm2708/patches-4.9/0132-Revert-bcm2835-i2s-Changes-for-allowing-asymmetric-s.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From db51b292d97ecb021831ed380ce4e1152b1bd235 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 16 Jan 2017 21:02:26 +0000
-Subject: [PATCH] Revert "bcm2835-i2s: Changes for allowing asymmetric sample
- formats."
-
-This reverts commit f5a6236a32e82068122301d246a94ca755d61704.
-
-See: https://github.com/raspberrypi/linux/issues/1799
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- sound/soc/bcm/bcm2835-i2s.c | 54 ++++++++++++++-------------------------------
- 1 file changed, 16 insertions(+), 38 deletions(-)
-
---- a/sound/soc/bcm/bcm2835-i2s.c
-+++ b/sound/soc/bcm/bcm2835-i2s.c
-@@ -237,9 +237,7 @@ static int bcm2835_i2s_hw_params(struct
- unsigned int sampling_rate = params_rate(params);
- unsigned int data_length, data_delay, bclk_ratio;
- unsigned int ch1pos, ch2pos, mode, format;
-- unsigned int previous_ftxp, previous_frxp;
- uint32_t csreg;
-- bool packed;
-
- /*
- * If a stream is already enabled,
-@@ -322,46 +320,26 @@ static int bcm2835_i2s_hw_params(struct
- return -EINVAL;
- }
-
-- /* Set the format for the matching stream direction. */
-- switch (substream->stream) {
-- case SNDRV_PCM_STREAM_PLAYBACK:
-- regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format);
-- break;
-- case SNDRV_PCM_STREAM_CAPTURE:
-- regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format);
-- break;
-- default:
-- return -EINVAL;
-- }
-+ /*
-+ * Set format for both streams.
-+ * We cannot set another frame length
-+ * (and therefore word length) anyway,
-+ * so the format will be the same.
-+ */
-+ regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format);
-+ regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format);
-
- /* Setup the I2S mode */
-- /* Keep existing FTXP and FRXP values. */
-- regmap_read(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, &mode);
--
-- previous_ftxp = mode & BCM2835_I2S_FTXP;
-- previous_frxp = mode & BCM2835_I2S_FRXP;
--
- mode = 0;
-
-- /*
-- * Retain the frame packed mode (2 channels per 32 bit word)
-- * of the other direction stream intact. The formats of each
-- * direction can be different as long as the frame length is
-- * shared for both.
-- */
-- packed = data_length <= 16;
--
-- switch (substream->stream) {
-- case SNDRV_PCM_STREAM_PLAYBACK:
-- mode |= previous_frxp;
-- mode |= packed ? BCM2835_I2S_FTXP : 0;
-- break;
-- case SNDRV_PCM_STREAM_CAPTURE:
-- mode |= previous_ftxp;
-- mode |= packed ? BCM2835_I2S_FRXP : 0;
-- break;
-- default:
-- return -EINVAL;
-+ if (data_length <= 16) {
-+ /*
-+ * Use frame packed mode (2 channels per 32 bit word)
-+ * We cannot set another frame length in the second stream
-+ * (and therefore word length) anyway,
-+ * so the format will be the same.
-+ */
-+ mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP;
- }
-
- mode |= BCM2835_I2S_FLEN(bclk_ratio - 1);
diff --git a/target/linux/brcm2708/patches-4.9/0138-ARM64-Use-dwc_otg-driver-by-default-for-USB.patch b/target/linux/brcm2708/patches-4.9/0133-ARM64-Use-dwc_otg-driver-by-default-for-USB.patch
index 05170990f7..53335b95fb 100644
--- a/target/linux/brcm2708/patches-4.9/0138-ARM64-Use-dwc_otg-driver-by-default-for-USB.patch
+++ b/target/linux/brcm2708/patches-4.9/0133-ARM64-Use-dwc_otg-driver-by-default-for-USB.patch
@@ -1,4 +1,4 @@
-From a81b40b75f5ae0feafcbc667394494e287cfe218 Mon Sep 17 00:00:00 2001
+From 4eec6ce872ac46987efeb9b9cdab0ad78a563bdb Mon Sep 17 00:00:00 2001
From: Michael Zoran <mzoran@crowfest.net>
Date: Sat, 14 Jan 2017 21:46:04 -0800
Subject: [PATCH] ARM64: Use dwc_otg driver by default for USB.
diff --git a/target/linux/brcm2708/patches-4.9/0139-BCM270X_DT-Add-reference-to-audio_pins-to-CM-dtb.patch b/target/linux/brcm2708/patches-4.9/0134-BCM270X_DT-Add-reference-to-audio_pins-to-CM-dtb.patch
index ed707a1cac..63df4a0378 100644
--- a/target/linux/brcm2708/patches-4.9/0139-BCM270X_DT-Add-reference-to-audio_pins-to-CM-dtb.patch
+++ b/target/linux/brcm2708/patches-4.9/0134-BCM270X_DT-Add-reference-to-audio_pins-to-CM-dtb.patch
@@ -1,4 +1,4 @@
-From 719ed1f8a1f93b2c9d855392a69493da107ae703 Mon Sep 17 00:00:00 2001
+From 8630b0b3fea31138c52ef83848ae1a047baa3855 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Mon, 23 Jan 2017 17:36:50 +0000
Subject: [PATCH] BCM270X_DT: Add reference to audio_pins to CM dtb
diff --git a/target/linux/brcm2708/patches-4.9/0140-config-Add-additional-network-scheduling-modules.patch b/target/linux/brcm2708/patches-4.9/0135-config-Add-additional-network-scheduling-modules.patch
index 91a00193c8..6c50870c7e 100644
--- a/target/linux/brcm2708/patches-4.9/0140-config-Add-additional-network-scheduling-modules.patch
+++ b/target/linux/brcm2708/patches-4.9/0135-config-Add-additional-network-scheduling-modules.patch
@@ -1,4 +1,4 @@
-From 6a4bb2c83c31f2d35397469454c3a54fbc32fce7 Mon Sep 17 00:00:00 2001
+From 56aef4ffcf12fdede0dad012de939c5a7c9cc55b Mon Sep 17 00:00:00 2001
From: popcornmix <popcornmix@gmail.com>
Date: Wed, 25 Jan 2017 11:30:38 +0000
Subject: [PATCH] config: Add additional network scheduling modules
diff --git a/target/linux/brcm2708/patches-4.9/0141-ASoC-A-simple-card-overlay-for-ADAU7002.patch b/target/linux/brcm2708/patches-4.9/0136-ASoC-A-simple-card-overlay-for-ADAU7002.patch
index 99e9414cc3..4f122fcdb0 100644
--- a/target/linux/brcm2708/patches-4.9/0141-ASoC-A-simple-card-overlay-for-ADAU7002.patch
+++ b/target/linux/brcm2708/patches-4.9/0136-ASoC-A-simple-card-overlay-for-ADAU7002.patch
@@ -1,4 +1,4 @@
-From 05f8935c02d5f598055afc773d5bee2f2d91dff2 Mon Sep 17 00:00:00 2001
+From 1cd1f19adbe020544e18193a006af9c71c8c82ca Mon Sep 17 00:00:00 2001
From: chris johnson <plasticchris@gmail.com>
Date: Sun, 22 Jan 2017 03:27:31 +0000
Subject: [PATCH] ASoC: A simple-card overlay for ADAU7002
diff --git a/target/linux/brcm2708/patches-4.9/0142-config-Add-SND_SOC_ADAU7002-codec-module.patch b/target/linux/brcm2708/patches-4.9/0137-config-Add-SND_SOC_ADAU7002-codec-module.patch
index ab642957bb..e4ef715fb3 100644
--- a/target/linux/brcm2708/patches-4.9/0142-config-Add-SND_SOC_ADAU7002-codec-module.patch
+++ b/target/linux/brcm2708/patches-4.9/0137-config-Add-SND_SOC_ADAU7002-codec-module.patch
@@ -1,4 +1,4 @@
-From 86a9b1e76dd131156f3fa0436ee6bac7bd51bd90 Mon Sep 17 00:00:00 2001
+From 30db626576fa53cb6a0a27311baed4dd5c296c38 Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 25 Jan 2017 21:17:23 +0000
Subject: [PATCH] config: Add SND_SOC_ADAU7002 codec module
diff --git a/target/linux/brcm2708/patches-4.9/0143-Add-overlay-for-mcp3008-adc-1818.patch b/target/linux/brcm2708/patches-4.9/0138-Add-overlay-for-mcp3008-adc-1818.patch
index 57b3605c55..560dc6c854 100644
--- a/target/linux/brcm2708/patches-4.9/0143-Add-overlay-for-mcp3008-adc-1818.patch
+++ b/target/linux/brcm2708/patches-4.9/0138-Add-overlay-for-mcp3008-adc-1818.patch
@@ -1,4 +1,4 @@
-From ad0138f3a91bebc14be78809d738c302f0ac311d Mon Sep 17 00:00:00 2001
+From 33800ba2a14ff23db96fe5ea6e421a731f60c52b Mon Sep 17 00:00:00 2001
From: Scott Ellis <scott@jumpnowtek.com>
Date: Fri, 27 Jan 2017 06:42:42 -0500
Subject: [PATCH] Add overlay for mcp3008 adc (#1818)
diff --git a/target/linux/brcm2708/patches-4.9/0144-usb-dwc2-Avoid-suspending-if-we-re-in-gadget-mode-18.patch b/target/linux/brcm2708/patches-4.9/0139-usb-dwc2-Avoid-suspending-if-we-re-in-gadget-mode-18.patch
index cd82d4f8bc..1ed31c2d2e 100644
--- a/target/linux/brcm2708/patches-4.9/0144-usb-dwc2-Avoid-suspending-if-we-re-in-gadget-mode-18.patch
+++ b/target/linux/brcm2708/patches-4.9/0139-usb-dwc2-Avoid-suspending-if-we-re-in-gadget-mode-18.patch
@@ -1,4 +1,4 @@
-From 7158cd0f806c91291c4f8e7c2e2b7e5be3023d30 Mon Sep 17 00:00:00 2001
+From 2ca9749f5b4326dad52756eaf5e7865504b4d374 Mon Sep 17 00:00:00 2001
From: ED6E0F17 <edge@karikoa.net>
Date: Fri, 3 Feb 2017 14:52:42 +0000
Subject: [PATCH] usb: dwc2: Avoid suspending if we're in gadget mode (#1825)
diff --git a/target/linux/brcm2708/patches-4.9/0150-gpio_mem-Remove-unnecessary-dev_info-output-1830.patch b/target/linux/brcm2708/patches-4.9/0140-gpio_mem-Remove-unnecessary-dev_info-output-1830.patch
index 19d23fc630..8c2d162ccd 100644
--- a/target/linux/brcm2708/patches-4.9/0150-gpio_mem-Remove-unnecessary-dev_info-output-1830.patch
+++ b/target/linux/brcm2708/patches-4.9/0140-gpio_mem-Remove-unnecessary-dev_info-output-1830.patch
@@ -1,4 +1,4 @@
-From 6a2c90127ab305604fa51f30bce4f23179fa4b63 Mon Sep 17 00:00:00 2001
+From 5ff260778264ec512ea879cea455c86d515cc6ba Mon Sep 17 00:00:00 2001
From: JamesH65 <JamesH65@users.noreply.github.com>
Date: Mon, 6 Feb 2017 15:24:47 +0000
Subject: [PATCH] gpio_mem: Remove unnecessary dev_info output (#1830)
diff --git a/target/linux/brcm2708/patches-4.9/0145-config-Enable-regulator-support.patch b/target/linux/brcm2708/patches-4.9/0141-config-Enable-regulator-support.patch
index 4c8cba110a..bcd766f4d3 100644
--- a/target/linux/brcm2708/patches-4.9/0145-config-Enable-regulator-support.patch
+++ b/target/linux/brcm2708/patches-4.9/0141-config-Enable-regulator-support.patch
@@ -1,4 +1,4 @@
-From 92105f7981fd207add7a09ace4570c9cd74f8757 Mon Sep 17 00:00:00 2001
+From e36583656552b7827a1b9d513ec39e95efa7ce8d Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:36 +0100
Subject: [PATCH] config: Enable regulator support
diff --git a/target/linux/brcm2708/patches-4.9/0146-BCM270x-DT-expose-3.3V-and-5V-system-rails.patch b/target/linux/brcm2708/patches-4.9/0142-BCM270x-DT-expose-3.3V-and-5V-system-rails.patch
index 0deaa0ab63..062e6e0256 100644
--- a/target/linux/brcm2708/patches-4.9/0146-BCM270x-DT-expose-3.3V-and-5V-system-rails.patch
+++ b/target/linux/brcm2708/patches-4.9/0142-BCM270x-DT-expose-3.3V-and-5V-system-rails.patch
@@ -1,4 +1,4 @@
-From 06b6fe1687cc560f36976cef615d38071ae07867 Mon Sep 17 00:00:00 2001
+From 3e2cb84235e904f0c127d34705852ba7893ec9ae Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:36 +0100
Subject: [PATCH] BCM270x DT: expose 3.3V and 5V system rails
diff --git a/target/linux/brcm2708/patches-4.9/0147-BCM270x-DT-Consolidate-audio-card-overlays.patch b/target/linux/brcm2708/patches-4.9/0143-BCM270x-DT-Consolidate-audio-card-overlays.patch
index d865199317..4c123b414c 100644
--- a/target/linux/brcm2708/patches-4.9/0147-BCM270x-DT-Consolidate-audio-card-overlays.patch
+++ b/target/linux/brcm2708/patches-4.9/0143-BCM270x-DT-Consolidate-audio-card-overlays.patch
@@ -1,4 +1,4 @@
-From 05798b17d672768e9e2c54c0c94df2ef019afe95 Mon Sep 17 00:00:00 2001
+From f134380c19eb38bc276d6d86fa575821c3493c60 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:36 +0100
Subject: [PATCH] BCM270x DT: Consolidate audio card overlays
diff --git a/target/linux/brcm2708/patches-4.9/0148-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch b/target/linux/brcm2708/patches-4.9/0144-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch
index 5c343bae91..863d107541 100644
--- a/target/linux/brcm2708/patches-4.9/0148-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch
+++ b/target/linux/brcm2708/patches-4.9/0144-ASoC-Add-driver-for-Cirrus-Logic-Audio-Card.patch
@@ -1,4 +1,4 @@
-From 8729879667d0668f20bd2aba8473879ac1d0216d Mon Sep 17 00:00:00 2001
+From 01c84e09a331a3b4c29c1cd5ce364c91577c7cea Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:37 +0100
Subject: [PATCH] ASoC: Add driver for Cirrus Logic Audio Card
diff --git a/target/linux/brcm2708/patches-4.9/0149-config-enable-Cirrus-Logic-Audio-Card.patch b/target/linux/brcm2708/patches-4.9/0145-config-enable-Cirrus-Logic-Audio-Card.patch
index c9e4fd1eea..be16a47d2b 100644
--- a/target/linux/brcm2708/patches-4.9/0149-config-enable-Cirrus-Logic-Audio-Card.patch
+++ b/target/linux/brcm2708/patches-4.9/0145-config-enable-Cirrus-Logic-Audio-Card.patch
@@ -1,4 +1,4 @@
-From e12d55ad45094a50ff25b70d76381bc7798ea3d5 Mon Sep 17 00:00:00 2001
+From e34099818448051c8fa84634534dff081540c7b7 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <hias@horus.com>
Date: Sun, 22 Jan 2017 12:49:37 +0100
Subject: [PATCH] config: enable Cirrus Logic Audio Card
diff --git a/target/linux/brcm2708/patches-4.9/0146-irq-bcm2836-Avoid-Invalid-trigger-warning.patch b/target/linux/brcm2708/patches-4.9/0146-irq-bcm2836-Avoid-Invalid-trigger-warning.patch
new file mode 100644
index 0000000000..db9fd39d48
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0146-irq-bcm2836-Avoid-Invalid-trigger-warning.patch
@@ -0,0 +1,24 @@
+From 4a849cef15885cf5dd901fafe45d3fa51b2b2a09 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 9 Feb 2017 14:33:30 +0000
+Subject: [PATCH] irq-bcm2836: Avoid "Invalid trigger warning"
+
+Initialise the level for each IRQ to avoid a warning from the
+arm arch timer code.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/irqchip/irq-bcm2836.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/irqchip/irq-bcm2836.c
++++ b/drivers/irqchip/irq-bcm2836.c
+@@ -178,7 +178,7 @@ static void bcm2836_arm_irqchip_register
+
+ irq_set_percpu_devid(irq);
+ irq_set_chip_and_handler(irq, chip, handle_percpu_devid_irq);
+- irq_set_status_flags(irq, IRQ_NOAUTOEN);
++ irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_TYPE_LEVEL_LOW);
+ }
+
+ static void
diff --git a/target/linux/brcm2708/patches-4.9/0147-sound-Demote-deferral-errors-to-INFO-level.patch b/target/linux/brcm2708/patches-4.9/0147-sound-Demote-deferral-errors-to-INFO-level.patch
new file mode 100644
index 0000000000..0a08eb9a1d
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0147-sound-Demote-deferral-errors-to-INFO-level.patch
@@ -0,0 +1,35 @@
+From b78e78fa375e3aa1e91b35030e8dfc930ba425f2 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 9 Feb 2017 14:36:44 +0000
+Subject: [PATCH] sound: Demote deferral errors to INFO level
+
+At present there is no mechanism to specify driver load order,
+which can lead to deferrals and repeated retries until successful.
+Since this situation is expected, reduce the dmesg level to
+INFO and mention that the operation will be retried.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ sound/soc/soc-core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1013,7 +1013,7 @@ static int soc_bind_dai_link(struct snd_
+ cpu_dai_component.dai_name = dai_link->cpu_dai_name;
+ rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
+ if (!rtd->cpu_dai) {
+- dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
++ dev_info(card->dev, "ASoC: CPU DAI %s not registered - will retry\n",
+ dai_link->cpu_dai_name);
+ goto _err_defer;
+ }
+@@ -1025,7 +1025,7 @@ static int soc_bind_dai_link(struct snd_
+ for (i = 0; i < rtd->num_codecs; i++) {
+ codec_dais[i] = snd_soc_find_dai(&codecs[i]);
+ if (!codec_dais[i]) {
+- dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
++ dev_info(card->dev, "ASoC: CODEC DAI %s not registered - will retry\n",
+ codecs[i].dai_name);
+ goto _err_defer;
+ }
diff --git a/target/linux/brcm2708/patches-4.9/0148-sound-Suppress-error-message-about-deferrals.patch b/target/linux/brcm2708/patches-4.9/0148-sound-Suppress-error-message-about-deferrals.patch
new file mode 100644
index 0000000000..52e36b5332
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0148-sound-Suppress-error-message-about-deferrals.patch
@@ -0,0 +1,217 @@
+From 6ebd83ad7b2bff00ad3e25811c38e73bb4201b07 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 9 Feb 2017 14:40:33 +0000
+Subject: [PATCH] sound: Suppress error message about deferrals
+
+Since driver load deferrals are expected and will already
+have resulted in a kernel message, suppress an essentially
+duplicate error message from the RPi audio board drivers.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ sound/soc/bcm/adau1977-adc.c | 2 +-
+ sound/soc/bcm/allo-piano-dac.c | 2 +-
+ sound/soc/bcm/digidac1-soundcard.c | 4 ++--
+ sound/soc/bcm/dionaudio_loco.c | 2 +-
+ sound/soc/bcm/hifiberry_amp.c | 3 +--
+ sound/soc/bcm/hifiberry_dac.c | 2 +-
+ sound/soc/bcm/hifiberry_dacplus.c | 2 +-
+ sound/soc/bcm/hifiberry_digi.c | 2 +-
+ sound/soc/bcm/iqaudio-dac.c | 5 +++--
+ sound/soc/bcm/iqaudio_digi.c | 2 +-
+ sound/soc/bcm/justboom-dac.c | 2 +-
+ sound/soc/bcm/justboom-digi.c | 2 +-
+ sound/soc/bcm/pisound.c | 3 ++-
+ sound/soc/bcm/raspidac3.c | 2 +-
+ sound/soc/bcm/rpi-dac.c | 2 +-
+ sound/soc/bcm/rpi-proto.c | 3 +--
+ 16 files changed, 20 insertions(+), 20 deletions(-)
+
+--- a/sound/soc/bcm/adau1977-adc.c
++++ b/sound/soc/bcm/adau1977-adc.c
+@@ -90,7 +90,7 @@ static int snd_adau1977_adc_probe(struct
+ }
+
+ ret = snd_soc_register_card(&snd_adau1977_adc);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+--- a/sound/soc/bcm/allo-piano-dac.c
++++ b/sound/soc/bcm/allo-piano-dac.c
+@@ -109,7 +109,7 @@ static int snd_allo_piano_dac_probe(stru
+ }
+
+ ret = snd_soc_register_card(&snd_allo_piano_dac);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+
+--- a/sound/soc/bcm/digidac1-soundcard.c
++++ b/sound/soc/bcm/digidac1-soundcard.c
+@@ -387,9 +387,9 @@ static int digidac1_soundcard_probe(stru
+ }
+
+ ret = snd_soc_register_card(&digidac1_soundcard);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+- ret);
++ ret);
+
+ return ret;
+ }
+--- a/sound/soc/bcm/dionaudio_loco.c
++++ b/sound/soc/bcm/dionaudio_loco.c
+@@ -86,7 +86,7 @@ static int snd_rpi_dionaudio_loco_probe(
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_dionaudio_loco);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+
+--- a/sound/soc/bcm/hifiberry_amp.c
++++ b/sound/soc/bcm/hifiberry_amp.c
+@@ -96,9 +96,8 @@ static int snd_rpi_hifiberry_amp_probe(s
+
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_amp);
+
+- if (ret != 0) {
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+- }
+
+ return ret;
+ }
+--- a/sound/soc/bcm/hifiberry_dac.c
++++ b/sound/soc/bcm/hifiberry_dac.c
+@@ -90,7 +90,7 @@ static int snd_rpi_hifiberry_dac_probe(s
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dac);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+--- a/sound/soc/bcm/hifiberry_dacplus.c
++++ b/sound/soc/bcm/hifiberry_dacplus.c
+@@ -324,7 +324,7 @@ static int snd_rpi_hifiberry_dacplus_pro
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+
+--- a/sound/soc/bcm/hifiberry_digi.c
++++ b/sound/soc/bcm/hifiberry_digi.c
+@@ -242,7 +242,7 @@ static int snd_rpi_hifiberry_digi_probe(
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_hifiberry_digi);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+--- a/sound/soc/bcm/iqaudio-dac.c
++++ b/sound/soc/bcm/iqaudio-dac.c
+@@ -197,8 +197,9 @@ static int snd_rpi_iqaudio_dac_probe(str
+
+ ret = snd_soc_register_card(&snd_rpi_iqaudio_dac);
+ if (ret) {
+- dev_err(&pdev->dev,
+- "snd_soc_register_card() failed: %d\n", ret);
++ if (ret != -EPROBE_DEFER)
++ dev_err(&pdev->dev,
++ "snd_soc_register_card() failed: %d\n", ret);
+ return ret;
+ }
+
+--- a/sound/soc/bcm/iqaudio_digi.c
++++ b/sound/soc/bcm/iqaudio_digi.c
+@@ -204,7 +204,7 @@ static int snd_rpi_iqaudio_digi_probe(st
+ }
+
+ ret = snd_soc_register_card(card);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
+
+--- a/sound/soc/bcm/justboom-dac.c
++++ b/sound/soc/bcm/justboom-dac.c
+@@ -128,7 +128,7 @@ static int snd_rpi_justboom_dac_probe(st
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_justboom_dac);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+
+--- a/sound/soc/bcm/justboom-digi.c
++++ b/sound/soc/bcm/justboom-digi.c
+@@ -181,7 +181,7 @@ static int snd_rpi_justboom_digi_probe(s
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_justboom_digi);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+
+--- a/sound/soc/bcm/pisound.c
++++ b/sound/soc/bcm/pisound.c
+@@ -1076,7 +1076,8 @@ static int pisnd_probe(struct platform_d
+ ret = snd_soc_register_card(&pisnd_card);
+
+ if (ret < 0) {
+- printe("snd_soc_register_card() failed: %d\n", ret);
++ if (ret != -EPROBE_DEFER)
++ printe("snd_soc_register_card() failed: %d\n", ret);
+ pisnd_uninit_gpio();
+ kobject_put(pisnd_kobj);
+ pisnd_spi_uninit();
+--- a/sound/soc/bcm/raspidac3.c
++++ b/sound/soc/bcm/raspidac3.c
+@@ -149,7 +149,7 @@ static int snd_rpi_raspidac3_probe(struc
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_raspidac3);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+
+--- a/sound/soc/bcm/rpi-dac.c
++++ b/sound/soc/bcm/rpi-dac.c
+@@ -85,7 +85,7 @@ static int snd_rpi_rpi_dac_probe(struct
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_rpi_dac);
+- if (ret)
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+ return ret;
+--- a/sound/soc/bcm/rpi-proto.c
++++ b/sound/soc/bcm/rpi-proto.c
+@@ -117,10 +117,9 @@ static int snd_rpi_proto_probe(struct pl
+ }
+
+ ret = snd_soc_register_card(&snd_rpi_proto);
+- if (ret) {
++ if (ret && ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "snd_soc_register_card() failed: %d\n", ret);
+- }
+
+ return ret;
+ }
diff --git a/target/linux/brcm2708/patches-4.9/0149-Update-vfpmodule.c.patch b/target/linux/brcm2708/patches-4.9/0149-Update-vfpmodule.c.patch
new file mode 100644
index 0000000000..16d740aafb
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0149-Update-vfpmodule.c.patch
@@ -0,0 +1,137 @@
+From aa00ca3b0296c40a6b5a1ad32258d5b655a28c70 Mon Sep 17 00:00:00 2001
+From: Claggy3 <stephen.maclagan@hotmail.com>
+Date: Sat, 11 Feb 2017 14:00:30 +0000
+Subject: [PATCH] Update vfpmodule.c
+
+Christopher Alexander Tobias Schulze - May 2, 2015, 11:57 a.m.
+This patch fixes a problem with VFP state save and restore related
+to exception handling (panic with message "BUG: unsupported FP
+instruction in kernel mode") present on VFP11 floating point units
+(as used with ARM1176JZF-S CPUs, e.g. on first generation Raspberry
+Pi boards). This patch was developed and discussed on
+
+ https://github.com/raspberrypi/linux/issues/859
+
+A precondition to see the crashes is that floating point exception
+traps are enabled. In this case, the VFP11 might determine that a FPU
+operation needs to trap at a point in time when it is not possible to
+signal this to the ARM11 core any more. The VFP11 will then set the
+FPEXC.EX bit and store the trapped opcode in FPINST. (In some cases,
+a second opcode might have been accepted by the VFP11 before the
+exception was detected and could be reported to the ARM11 - in this
+case, the VFP11 also sets FPEXC.FP2V and stores the second opcode in
+FPINST2.)
+
+If FPEXC.EX is set, the VFP11 will "bounce" the next FPU opcode issued
+by the ARM11 CPU, which will be seen by the ARM11 as an undefined opcode
+trap. The VFP support code examines the FPEXC.EX and FPEXC.FP2V bits
+to decide what actions to take, i.e., whether to emulate the opcodes
+found in FPINST and FPINST2, and whether to retry the bounced instruction.
+
+If a user space application has left the VFP11 in this "pending trap"
+state, the next FPU opcode issued to the VFP11 might actually be the
+VSTMIA operation vfp_save_state() uses to store the FPU registers
+to memory (in our test cases, when building the signal stack frame).
+In this case, the kernel crashes as described above.
+
+This patch fixes the problem by making sure that vfp_save_state() is
+always entered with FPEXC.EX cleared. (The current value of FPEXC has
+already been saved, so this does not corrupt the context. Clearing
+FPEXC.EX has no effects on FPINST or FPINST2. Also note that many
+callers already modify FPEXC by setting FPEXC.EN before invoking
+vfp_save_state().)
+
+This patch also addresses a second problem related to FPEXC.EX: After
+returning from signal handling, the kernel reloads the VFP context
+from the user mode stack. However, the current code explicitly clears
+both FPEXC.EX and FPEXC.FP2V during reload. As VFP11 requires these
+bits to be preserved, this patch disables clearing them for VFP
+implementations belonging to architecture 1. There should be no
+negative side effects: the user can set both bits by executing FPU
+opcodes anyway, and while user code may now place arbitrary values
+into FPINST and FPINST2 (e.g., non-VFP ARM opcodes) the VFP support
+code knows which instructions can be emulated, and rejects other
+opcodes with "unhandled bounce" messages, so there should be no
+security impact from allowing reloading FPEXC.EX and FPEXC.FP2V.
+
+Signed-off-by: Christopher Alexander Tobias Schulze <cat.schulze@alice-dsl.net>
+---
+ arch/arm/vfp/vfpmodule.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+--- a/arch/arm/vfp/vfpmodule.c
++++ b/arch/arm/vfp/vfpmodule.c
+@@ -179,8 +179,11 @@ static int vfp_notifier(struct notifier_
+ * case the thread migrates to a different CPU. The
+ * restoring is done lazily.
+ */
+- if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu])
++ if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu]) {
++ /* vfp_save_state oopses on VFP11 if EX bit set */
++ fmxr(FPEXC, fpexc & ~FPEXC_EX);
+ vfp_save_state(vfp_current_hw_state[cpu], fpexc);
++ }
+ #endif
+
+ /*
+@@ -463,13 +466,16 @@ static int vfp_pm_suspend(void)
+ /* if vfp is on, then save state for resumption */
+ if (fpexc & FPEXC_EN) {
+ pr_debug("%s: saving vfp state\n", __func__);
++ /* vfp_save_state oopses on VFP11 if EX bit set */
++ fmxr(FPEXC, fpexc & ~FPEXC_EX);
+ vfp_save_state(&ti->vfpstate, fpexc);
+
+ /* disable, just in case */
+ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+ } else if (vfp_current_hw_state[ti->cpu]) {
+ #ifndef CONFIG_SMP
+- fmxr(FPEXC, fpexc | FPEXC_EN);
++ /* vfp_save_state oopses on VFP11 if EX bit set */
++ fmxr(FPEXC, (fpexc & ~FPEXC_EX) | FPEXC_EN);
+ vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc);
+ fmxr(FPEXC, fpexc);
+ #endif
+@@ -532,7 +538,8 @@ void vfp_sync_hwstate(struct thread_info
+ /*
+ * Save the last VFP state on this CPU.
+ */
+- fmxr(FPEXC, fpexc | FPEXC_EN);
++ /* vfp_save_state oopses on VFP11 if EX bit set */
++ fmxr(FPEXC, (fpexc & ~FPEXC_EX) | FPEXC_EN);
+ vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN);
+ fmxr(FPEXC, fpexc);
+ }
+@@ -604,6 +611,7 @@ int vfp_restore_user_hwstate(struct user
+ struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
+ unsigned long fpexc;
+ int err = 0;
++ u32 fpsid = fmrx(FPSID);
+
+ /* Disable VFP to avoid corrupting the new thread state. */
+ vfp_flush_hwstate(thread);
+@@ -627,8 +635,12 @@ int vfp_restore_user_hwstate(struct user
+ /* Ensure the VFP is enabled. */
+ fpexc |= FPEXC_EN;
+
+- /* Ensure FPINST2 is invalid and the exception flag is cleared. */
+- fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
++ /* Mask FPXEC_EX and FPEXC_FP2V if not required by VFP arch */
++ if ((fpsid & FPSID_ARCH_MASK) != (1 << FPSID_ARCH_BIT)) {
++ /* Ensure FPINST2 is invalid and the exception flag is cleared. */
++ fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
++ }
++
+ hwstate->fpexc = fpexc;
+
+ __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
+@@ -698,7 +710,8 @@ void kernel_neon_begin(void)
+ cpu = get_cpu();
+
+ fpexc = fmrx(FPEXC) | FPEXC_EN;
+- fmxr(FPEXC, fpexc);
++ /* vfp_save_state oopses on VFP11 if EX bit set */
++ fmxr(FPEXC, fpexc & ~FPEXC_EX);
+
+ /*
+ * Save the userland NEON/VFP state. Under UP,
diff --git a/target/linux/brcm2708/patches-4.9/0150-dwc_otg-fix-summarize-urb-actual_length-for-isochron.patch b/target/linux/brcm2708/patches-4.9/0150-dwc_otg-fix-summarize-urb-actual_length-for-isochron.patch
new file mode 100644
index 0000000000..295db595ca
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0150-dwc_otg-fix-summarize-urb-actual_length-for-isochron.patch
@@ -0,0 +1,28 @@
+From f9efb72c44da2cce9cceca01c8f6118ec1605c69 Mon Sep 17 00:00:00 2001
+From: Martin Cerveny <M.Cerveny@computer.org>
+Date: Mon, 13 Feb 2017 17:23:47 +0100
+Subject: [PATCH] dwc_otg: fix summarize urb->actual_length for isochronous
+ transfers
+
+Kernel does not copy input data of ISO transfers to userspace
+if actual_length is set only in ISO transfers and not summarized
+in urb->actual_length. Fixes raspberrypi/linux#903
+---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+@@ -334,10 +334,12 @@ static int _complete(dwc_otg_hcd_t * hcd
+ int i;
+
+ urb->error_count = dwc_otg_hcd_urb_get_error_count(dwc_otg_urb);
++ urb->actual_length = 0;
+ for (i = 0; i < urb->number_of_packets; ++i) {
+ urb->iso_frame_desc[i].actual_length =
+ dwc_otg_hcd_urb_get_iso_desc_actual_length
+ (dwc_otg_urb, i);
++ urb->actual_length += urb->iso_frame_desc[i].actual_length;
+ urb->iso_frame_desc[i].status =
+ dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i);
+ }
diff --git a/target/linux/brcm2708/patches-4.9/0151-clk-bcm2835-Fix-fixed_divider-of-pllh_aux.patch b/target/linux/brcm2708/patches-4.9/0151-clk-bcm2835-Fix-fixed_divider-of-pllh_aux.patch
new file mode 100644
index 0000000000..82f462847b
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0151-clk-bcm2835-Fix-fixed_divider-of-pllh_aux.patch
@@ -0,0 +1,27 @@
+From b8ded4dca34feafd33f22eff47d19b17b7dd83f4 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Tue, 22 Nov 2016 12:45:28 -0800
+Subject: [PATCH] clk: bcm2835: Fix ->fixed_divider of pllh_aux
+
+There is no fixed divider on pllh_aux.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit f2a46926aba1f0c33944901d2420a6a887455ddc)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1607,7 +1607,7 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLH_AUX,
+ .load_mask = CM_PLLH_LOADAUX,
+ .hold_mask = 0,
+- .fixed_divider = 10),
++ .fixed_divider = 1),
+ [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
+ .name = "pllh_pix",
+ .source_pll = "pllh",
diff --git a/target/linux/brcm2708/patches-4.9/0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch b/target/linux/brcm2708/patches-4.9/0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch
new file mode 100644
index 0000000000..448b0375b3
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0152-clk-bcm-Support-rate-change-propagation-on-bcm2835-c.patch
@@ -0,0 +1,124 @@
+From 2988239956fddb3fb808cfb50fa8d4e68b893f3d Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Thu, 1 Dec 2016 22:00:19 +0100
+Subject: [PATCH] clk: bcm: Support rate change propagation on bcm2835 clocks
+
+Some peripheral clocks, like the VEC (Video EnCoder) clock need to be set
+to a precise rate (in our case 108MHz). With the current implementation,
+where peripheral clocks are not allowed to forward rate change requests
+to their parents, it is impossible to match this requirement unless the
+bootloader has configured things correctly, or a specific rate has been
+assigned through the DT (with the assigned-clk-rates property).
+
+Add a new field to struct bcm2835_clock_data to specify which parent
+clocks accept rate change propagation, and support set rate propagation
+in bcm2835_clock_determine_rate().
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit 155e8b3b0ee320ae866b97dd31eba8a1f080a772)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 67 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 63 insertions(+), 4 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -436,6 +436,9 @@ struct bcm2835_clock_data {
+ const char *const *parents;
+ int num_mux_parents;
+
++ /* Bitmap encoding which parents accept rate change propagation. */
++ unsigned int set_rate_parent;
++
+ u32 ctl_reg;
+ u32 div_reg;
+
+@@ -1017,10 +1020,60 @@ bcm2835_clk_is_pllc(struct clk_hw *hw)
+ return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
+ }
+
++static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
++ int parent_idx,
++ unsigned long rate,
++ u32 *div,
++ unsigned long *prate)
++{
++ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
++ struct bcm2835_cprman *cprman = clock->cprman;
++ const struct bcm2835_clock_data *data = clock->data;
++ unsigned long best_rate;
++ u32 curdiv, mindiv, maxdiv;
++ struct clk_hw *parent;
++
++ parent = clk_hw_get_parent_by_index(hw, parent_idx);
++
++ if (!(BIT(parent_idx) & data->set_rate_parent)) {
++ *prate = clk_hw_get_rate(parent);
++ *div = bcm2835_clock_choose_div(hw, rate, *prate, true);
++
++ return bcm2835_clock_rate_from_divisor(clock, *prate,
++ *div);
++ }
++
++ if (data->frac_bits)
++ dev_warn(cprman->dev,
++ "frac bits are not used when propagating rate change");
++
++ /* clamp to min divider of 2 if we're dealing with a mash clock */
++ mindiv = data->is_mash_clock ? 2 : 1;
++ maxdiv = BIT(data->int_bits) - 1;
++
++ /* TODO: Be smart, and only test a subset of the available divisors. */
++ for (curdiv = mindiv; curdiv <= maxdiv; curdiv++) {
++ unsigned long tmp_rate;
++
++ tmp_rate = clk_hw_round_rate(parent, rate * curdiv);
++ tmp_rate /= curdiv;
++ if (curdiv == mindiv ||
++ (tmp_rate > best_rate && tmp_rate <= rate))
++ best_rate = tmp_rate;
++
++ if (best_rate == rate)
++ break;
++ }
++
++ *div = curdiv << CM_DIV_FRAC_BITS;
++ *prate = curdiv * best_rate;
++
++ return best_rate;
++}
++
+ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+ {
+- struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ struct clk_hw *parent, *best_parent = NULL;
+ bool current_parent_is_pllc;
+ unsigned long rate, best_rate = 0;
+@@ -1048,9 +1101,8 @@ static int bcm2835_clock_determine_rate(
+ if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
+ continue;
+
+- prate = clk_hw_get_rate(parent);
+- div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
+- rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
++ rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate,
++ &div, &prate);
+ if (rate > best_rate && rate <= req->rate) {
+ best_parent = parent;
+ best_prate = prate;
+@@ -1271,6 +1323,13 @@ static struct clk_hw *bcm2835_register_c
+ if ((cprman_read(cprman, data->ctl_reg) & CM_ENABLE) == 0)
+ init.flags &= ~CLK_IS_CRITICAL;
+
++ /*
++ * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate
++ * rate changes on at least of the parents.
++ */
++ if (data->set_rate_parent)
++ init.flags |= CLK_SET_RATE_PARENT;
++
+ if (data->is_vpu_clock) {
+ init.ops = &bcm2835_vpu_clock_clk_ops;
+ } else {
diff --git a/target/linux/brcm2708/patches-4.9/0153-clk-bcm-Allow-rate-change-propagation-to-PLLH_AUX-on.patch b/target/linux/brcm2708/patches-4.9/0153-clk-bcm-Allow-rate-change-propagation-to-PLLH_AUX-on.patch
new file mode 100644
index 0000000000..ed082abaa5
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0153-clk-bcm-Allow-rate-change-propagation-to-PLLH_AUX-on.patch
@@ -0,0 +1,35 @@
+From 5209e1b8f78fd1184f25cf19cf0daa58f4ad6599 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Thu, 1 Dec 2016 22:00:20 +0100
+Subject: [PATCH] clk: bcm: Allow rate change propagation to PLLH_AUX on VEC
+ clock
+
+The VEC clock requires needs to be set at exactly 108MHz. Allow rate
+change propagation on PLLH_AUX to match this requirement wihtout
+impacting other IPs (PLLH is currently only used by the HDMI encoder,
+which cannot be enabled when the VEC encoder is enabled).
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit d86d46af84855403c00018be1c3e7bc190f2a6cd)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1870,7 +1870,12 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_VECCTL,
+ .div_reg = CM_VECDIV,
+ .int_bits = 4,
+- .frac_bits = 0),
++ .frac_bits = 0,
++ /*
++ * Allow rate change propagation only on PLLH_AUX which is
++ * assigned index 7 in the parent array.
++ */
++ .set_rate_parent = BIT(7)),
+
+ /* dsi clocks */
+ [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
diff --git a/target/linux/brcm2708/patches-4.9/0154-clk-bcm-Fix-maybe-uninitialized-warning-in-bcm2835_c.patch b/target/linux/brcm2708/patches-4.9/0154-clk-bcm-Fix-maybe-uninitialized-warning-in-bcm2835_c.patch
new file mode 100644
index 0000000000..01e29775b9
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0154-clk-bcm-Fix-maybe-uninitialized-warning-in-bcm2835_c.patch
@@ -0,0 +1,29 @@
+From 9db88c2a81a12eb2b2953ee1f9090624fcc47dab Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Mon, 12 Dec 2016 09:00:53 +0100
+Subject: [PATCH] clk: bcm: Fix 'maybe-uninitialized' warning in
+ bcm2835_clock_choose_div_and_prate()
+
+best_rate is reported as potentially uninitialized by gcc.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Fixes: 155e8b3b0ee3 ("clk: bcm: Support rate change propagation on bcm2835 clocks")
+Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit 2aab7a2055a1705c9e30920d95a596226999eb21)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1029,7 +1029,7 @@ static unsigned long bcm2835_clock_choos
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ struct bcm2835_cprman *cprman = clock->cprman;
+ const struct bcm2835_clock_data *data = clock->data;
+- unsigned long best_rate;
++ unsigned long best_rate = 0;
+ u32 curdiv, mindiv, maxdiv;
+ struct clk_hw *parent;
+
diff --git a/target/linux/brcm2708/patches-4.9/0155-clk-bcm2835-Don-t-rate-change-PLLs-on-behalf-of-DSI-.patch b/target/linux/brcm2708/patches-4.9/0155-clk-bcm2835-Don-t-rate-change-PLLs-on-behalf-of-DSI-.patch
new file mode 100644
index 0000000000..154e061155
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0155-clk-bcm2835-Don-t-rate-change-PLLs-on-behalf-of-DSI-.patch
@@ -0,0 +1,172 @@
+From 999db52750c062708532e1357ea3942cc619794f Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 18 Jan 2017 07:31:55 +1100
+Subject: [PATCH] clk: bcm2835: Don't rate change PLLs on behalf of DSI PLL
+ dividers.
+
+Our core PLLs are intended to be configured once and left alone. With
+the SET_RATE_PARENT, asking to set the PLLD_DSI1 clock rate would
+change PLLD just to get closer to the requested DSI clock, thus
+changing PLLD_PER, the UART and ethernet PHY clock rates downstream of
+it, and breaking ethernet.
+
+We *do* want PLLH to change so that PLLH_AUX can be exactly the value
+we want, though. Thus, we need to have a per-divider policy of
+whether to pass rate changes up.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit 55486091bd1e1c5ed28c43c0d6b3392468a9adb5)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 42 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 28 insertions(+), 14 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -428,6 +428,7 @@ struct bcm2835_pll_divider_data {
+ u32 load_mask;
+ u32 hold_mask;
+ u32 fixed_divider;
++ u32 flags;
+ };
+
+ struct bcm2835_clock_data {
+@@ -1252,7 +1253,7 @@ bcm2835_register_pll_divider(struct bcm2
+ init.num_parents = 1;
+ init.name = divider_name;
+ init.ops = &bcm2835_pll_divider_clk_ops;
+- init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
++ init.flags = data->flags | CLK_IGNORE_UNUSED;
+
+ divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
+ if (!divider)
+@@ -1475,7 +1476,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLA_CORE,
+ .load_mask = CM_PLLA_LOADCORE,
+ .hold_mask = CM_PLLA_HOLDCORE,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
+ .name = "plla_per",
+ .source_pll = "plla",
+@@ -1483,7 +1485,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLA_PER,
+ .load_mask = CM_PLLA_LOADPER,
+ .hold_mask = CM_PLLA_HOLDPER,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV(
+ .name = "plla_dsi0",
+ .source_pll = "plla",
+@@ -1499,7 +1502,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLA_CCP2,
+ .load_mask = CM_PLLA_LOADCCP2,
+ .hold_mask = CM_PLLA_HOLDCCP2,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+
+ /* PLLB is used for the ARM's clock. */
+ [BCM2835_PLLB] = REGISTER_PLL(
+@@ -1523,7 +1527,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLB_ARM,
+ .load_mask = CM_PLLB_LOADARM,
+ .hold_mask = CM_PLLB_HOLDARM,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+
+ /*
+ * PLLC is the core PLL, used to drive the core VPU clock.
+@@ -1552,7 +1557,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLC_CORE0,
+ .load_mask = CM_PLLC_LOADCORE0,
+ .hold_mask = CM_PLLC_HOLDCORE0,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
+ .name = "pllc_core1",
+ .source_pll = "pllc",
+@@ -1560,7 +1566,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLC_CORE1,
+ .load_mask = CM_PLLC_LOADCORE1,
+ .hold_mask = CM_PLLC_HOLDCORE1,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
+ .name = "pllc_core2",
+ .source_pll = "pllc",
+@@ -1568,7 +1575,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLC_CORE2,
+ .load_mask = CM_PLLC_LOADCORE2,
+ .hold_mask = CM_PLLC_HOLDCORE2,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
+ .name = "pllc_per",
+ .source_pll = "pllc",
+@@ -1576,7 +1584,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLC_PER,
+ .load_mask = CM_PLLC_LOADPER,
+ .hold_mask = CM_PLLC_HOLDPER,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+
+ /*
+ * PLLD is the display PLL, used to drive DSI display panels.
+@@ -1605,7 +1614,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLD_CORE,
+ .load_mask = CM_PLLD_LOADCORE,
+ .hold_mask = CM_PLLD_HOLDCORE,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
+ .name = "plld_per",
+ .source_pll = "plld",
+@@ -1613,7 +1623,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLD_PER,
+ .load_mask = CM_PLLD_LOADPER,
+ .hold_mask = CM_PLLD_HOLDPER,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV(
+ .name = "plld_dsi0",
+ .source_pll = "plld",
+@@ -1658,7 +1669,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLH_RCAL,
+ .load_mask = CM_PLLH_LOADRCAL,
+ .hold_mask = 0,
+- .fixed_divider = 10),
++ .fixed_divider = 10,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
+ .name = "pllh_aux",
+ .source_pll = "pllh",
+@@ -1666,7 +1678,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLH_AUX,
+ .load_mask = CM_PLLH_LOADAUX,
+ .hold_mask = 0,
+- .fixed_divider = 1),
++ .fixed_divider = 1,
++ .flags = CLK_SET_RATE_PARENT),
+ [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
+ .name = "pllh_pix",
+ .source_pll = "pllh",
+@@ -1674,7 +1687,8 @@ static const struct bcm2835_clk_desc clk
+ .a2w_reg = A2W_PLLH_PIX,
+ .load_mask = CM_PLLH_LOADPIX,
+ .hold_mask = 0,
+- .fixed_divider = 10),
++ .fixed_divider = 10,
++ .flags = CLK_SET_RATE_PARENT),
+
+ /* the clocks */
+
diff --git a/target/linux/brcm2708/patches-4.9/0156-clk-bcm2835-Register-the-DSI0-DSI1-pixel-clocks.patch b/target/linux/brcm2708/patches-4.9/0156-clk-bcm2835-Register-the-DSI0-DSI1-pixel-clocks.patch
new file mode 100644
index 0000000000..24e8aedbdc
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0156-clk-bcm2835-Register-the-DSI0-DSI1-pixel-clocks.patch
@@ -0,0 +1,238 @@
+From 876f8ef32ec09fb566cc6ecdf4c96a8348f135b6 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 18 Jan 2017 07:31:56 +1100
+Subject: [PATCH] clk: bcm2835: Register the DSI0/DSI1 pixel clocks.
+
+The DSI pixel clocks are muxed from clocks generated in the analog phy
+by the DSI driver. In order to set them as parents, we need to do the
+same name lookup dance on them as we do for our root oscillator.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit 8a39e9fa578229fd4604266c6ebb1a3a77d7994c)
+---
+ .../bindings/clock/brcm,bcm2835-cprman.txt | 15 ++-
+ drivers/clk/bcm/clk-bcm2835.c | 121 +++++++++++++++++++--
+ include/dt-bindings/clock/bcm2835.h | 2 +
+ 3 files changed, 125 insertions(+), 13 deletions(-)
+
+--- a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
++++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt
+@@ -16,7 +16,20 @@ Required properties:
+ - #clock-cells: Should be <1>. The permitted clock-specifier values can be
+ found in include/dt-bindings/clock/bcm2835.h
+ - reg: Specifies base physical address and size of the registers
+-- clocks: The external oscillator clock phandle
++- clocks: phandles to the parent clocks used as input to the module, in
++ the following order:
++
++ - External oscillator
++ - DSI0 byte clock
++ - DSI0 DDR2 clock
++ - DSI0 DDR clock
++ - DSI1 byte clock
++ - DSI1 DDR2 clock
++ - DSI1 DDR clock
++
++ Only external oscillator is required. The DSI clocks may
++ not be present, in which case their children will be
++ unusable.
+
+ Example:
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -297,11 +297,32 @@
+ #define LOCK_TIMEOUT_NS 100000000
+ #define BCM2835_MAX_FB_RATE 1750000000u
+
++/*
++ * Names of clocks used within the driver that need to be replaced
++ * with an external parent's name. This array is in the order that
++ * the clocks node in the DT references external clocks.
++ */
++static const char *const cprman_parent_names[] = {
++ "xosc",
++ "dsi0_byte",
++ "dsi0_ddr2",
++ "dsi0_ddr",
++ "dsi1_byte",
++ "dsi1_ddr2",
++ "dsi1_ddr",
++};
++
+ struct bcm2835_cprman {
+ struct device *dev;
+ void __iomem *regs;
+ spinlock_t regs_lock; /* spinlock for all clocks */
+- const char *osc_name;
++
++ /*
++ * Real names of cprman clock parents looked up through
++ * of_clk_get_parent_name(), which will be used in the
++ * parent_names[] arrays for clock registration.
++ */
++ const char *real_parent_names[ARRAY_SIZE(cprman_parent_names)];
+
+ /* Must be last */
+ struct clk_hw_onecell_data onecell;
+@@ -907,6 +928,9 @@ static long bcm2835_clock_rate_from_divi
+ const struct bcm2835_clock_data *data = clock->data;
+ u64 temp;
+
++ if (data->int_bits == 0 && data->frac_bits == 0)
++ return parent_rate;
++
+ /*
+ * The divisor is a 12.12 fixed point field, but only some of
+ * the bits are populated in any given clock.
+@@ -930,7 +954,12 @@ static unsigned long bcm2835_clock_get_r
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ struct bcm2835_cprman *cprman = clock->cprman;
+ const struct bcm2835_clock_data *data = clock->data;
+- u32 div = cprman_read(cprman, data->div_reg);
++ u32 div;
++
++ if (data->int_bits == 0 && data->frac_bits == 0)
++ return parent_rate;
++
++ div = cprman_read(cprman, data->div_reg);
+
+ return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
+ }
+@@ -1209,7 +1238,7 @@ static struct clk_hw *bcm2835_register_p
+ memset(&init, 0, sizeof(init));
+
+ /* All of the PLLs derive from the external oscillator. */
+- init.parent_names = &cprman->osc_name;
++ init.parent_names = &cprman->real_parent_names[0];
+ init.num_parents = 1;
+ init.name = data->name;
+ init.ops = &bcm2835_pll_clk_ops;
+@@ -1295,18 +1324,22 @@ static struct clk_hw *bcm2835_register_c
+ struct bcm2835_clock *clock;
+ struct clk_init_data init;
+ const char *parents[1 << CM_SRC_BITS];
+- size_t i;
++ size_t i, j;
+ int ret;
+
+ /*
+- * Replace our "xosc" references with the oscillator's
+- * actual name.
++ * Replace our strings referencing parent clocks with the
++ * actual clock-output-name of the parent.
+ */
+ for (i = 0; i < data->num_mux_parents; i++) {
+- if (strcmp(data->parents[i], "xosc") == 0)
+- parents[i] = cprman->osc_name;
+- else
+- parents[i] = data->parents[i];
++ parents[i] = data->parents[i];
++
++ for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) {
++ if (strcmp(parents[i], cprman_parent_names[j]) == 0) {
++ parents[i] = cprman->real_parent_names[j];
++ break;
++ }
++ }
+ }
+
+ memset(&init, 0, sizeof(init));
+@@ -1442,6 +1475,47 @@ static const char *const bcm2835_clock_v
+ __VA_ARGS__)
+
+ /*
++ * DSI parent clocks. The DSI byte/DDR/DDR2 clocks come from the DSI
++ * analog PHY. The _inv variants are generated internally to cprman,
++ * but we don't use them so they aren't hooked up.
++ */
++static const char *const bcm2835_clock_dsi0_parents[] = {
++ "gnd",
++ "xosc",
++ "testdebug0",
++ "testdebug1",
++ "dsi0_ddr",
++ "dsi0_ddr_inv",
++ "dsi0_ddr2",
++ "dsi0_ddr2_inv",
++ "dsi0_byte",
++ "dsi0_byte_inv",
++};
++
++static const char *const bcm2835_clock_dsi1_parents[] = {
++ "gnd",
++ "xosc",
++ "testdebug0",
++ "testdebug1",
++ "dsi1_ddr",
++ "dsi1_ddr_inv",
++ "dsi1_ddr2",
++ "dsi1_ddr2_inv",
++ "dsi1_byte",
++ "dsi1_byte_inv",
++};
++
++#define REGISTER_DSI0_CLK(...) REGISTER_CLK( \
++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents), \
++ .parents = bcm2835_clock_dsi0_parents, \
++ __VA_ARGS__)
++
++#define REGISTER_DSI1_CLK(...) REGISTER_CLK( \
++ .num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents), \
++ .parents = bcm2835_clock_dsi1_parents, \
++ __VA_ARGS__)
++
++/*
+ * the real definition of all the pll, pll_dividers and clocks
+ * these make use of the above REGISTER_* macros
+ */
+@@ -1904,6 +1978,18 @@ static const struct bcm2835_clk_desc clk
+ .div_reg = CM_DSI1EDIV,
+ .int_bits = 4,
+ .frac_bits = 8),
++ [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK(
++ .name = "dsi0p",
++ .ctl_reg = CM_DSI0PCTL,
++ .div_reg = CM_DSI0PDIV,
++ .int_bits = 0,
++ .frac_bits = 0),
++ [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK(
++ .name = "dsi1p",
++ .ctl_reg = CM_DSI1PCTL,
++ .div_reg = CM_DSI1PDIV,
++ .int_bits = 0,
++ .frac_bits = 0),
+
+ /* the gates */
+
+@@ -1962,8 +2048,19 @@ static int bcm2835_clk_probe(struct plat
+ if (IS_ERR(cprman->regs))
+ return PTR_ERR(cprman->regs);
+
+- cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0);
+- if (!cprman->osc_name)
++ memcpy(cprman->real_parent_names, cprman_parent_names,
++ sizeof(cprman_parent_names));
++ of_clk_parent_fill(dev->of_node, cprman->real_parent_names,
++ ARRAY_SIZE(cprman_parent_names));
++
++ /*
++ * Make sure the external oscillator has been registered.
++ *
++ * The other (DSI) clocks are not present on older device
++ * trees, which we still need to support for backwards
++ * compatibility.
++ */
++ if (!cprman->real_parent_names[0])
+ return -ENODEV;
+
+ platform_set_drvdata(pdev, cprman);
+--- a/include/dt-bindings/clock/bcm2835.h
++++ b/include/dt-bindings/clock/bcm2835.h
+@@ -64,3 +64,5 @@
+ #define BCM2835_CLOCK_CAM1 46
+ #define BCM2835_CLOCK_DSI0E 47
+ #define BCM2835_CLOCK_DSI1E 48
++#define BCM2835_CLOCK_DSI0P 49
++#define BCM2835_CLOCK_DSI1P 50
diff --git a/target/linux/brcm2708/patches-4.9/0157-clk-bcm2835-Add-leaf-clock-measurement-support-disab.patch b/target/linux/brcm2708/patches-4.9/0157-clk-bcm2835-Add-leaf-clock-measurement-support-disab.patch
new file mode 100644
index 0000000000..16c5ec5cbf
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0157-clk-bcm2835-Add-leaf-clock-measurement-support-disab.patch
@@ -0,0 +1,346 @@
+From 546bac0479e51024027f8c8820f912573643b101 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 18 Jan 2017 07:31:57 +1100
+Subject: [PATCH] clk: bcm2835: Add leaf clock measurement support, disabled by
+ default
+
+This proved incredibly useful during debugging of the DSI driver, to
+see if our clocks were running at rate we requested. Let's leave it
+here for the next person interacting with clocks on the platform (and
+so that hopefully we can just hook it up to debugfs some day).
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+(cherry picked from commit 3f9195811d8d829556c4cd88d3f9e56a80d5ba60)
+---
+ drivers/clk/bcm/clk-bcm2835.c | 144 ++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 119 insertions(+), 25 deletions(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -39,6 +39,7 @@
+ #include <linux/clk.h>
+ #include <linux/clk/bcm2835.h>
+ #include <linux/debugfs.h>
++#include <linux/delay.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+@@ -98,7 +99,8 @@
+ #define CM_SMIDIV 0x0b4
+ /* no definition for 0x0b8 and 0x0bc */
+ #define CM_TCNTCTL 0x0c0
+-#define CM_TCNTDIV 0x0c4
++# define CM_TCNT_SRC1_SHIFT 12
++#define CM_TCNTCNT 0x0c4
+ #define CM_TECCTL 0x0c8
+ #define CM_TECDIV 0x0cc
+ #define CM_TD0CTL 0x0d0
+@@ -338,6 +340,61 @@ static inline u32 cprman_read(struct bcm
+ return readl(cprman->regs + reg);
+ }
+
++/* Does a cycle of measuring a clock through the TCNT clock, which may
++ * source from many other clocks in the system.
++ */
++static unsigned long bcm2835_measure_tcnt_mux(struct bcm2835_cprman *cprman,
++ u32 tcnt_mux)
++{
++ u32 osccount = 19200; /* 1ms */
++ u32 count;
++ ktime_t timeout;
++
++ spin_lock(&cprman->regs_lock);
++
++ cprman_write(cprman, CM_TCNTCTL, CM_KILL);
++
++ cprman_write(cprman, CM_TCNTCTL,
++ (tcnt_mux & CM_SRC_MASK) |
++ (tcnt_mux >> CM_SRC_BITS) << CM_TCNT_SRC1_SHIFT);
++
++ cprman_write(cprman, CM_OSCCOUNT, osccount);
++
++ /* do a kind delay at the start */
++ mdelay(1);
++
++ /* Finish off whatever is left of OSCCOUNT */
++ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
++ while (cprman_read(cprman, CM_OSCCOUNT)) {
++ if (ktime_after(ktime_get(), timeout)) {
++ dev_err(cprman->dev, "timeout waiting for OSCCOUNT\n");
++ count = 0;
++ goto out;
++ }
++ cpu_relax();
++ }
++
++ /* Wait for BUSY to clear. */
++ timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
++ while (cprman_read(cprman, CM_TCNTCTL) & CM_BUSY) {
++ if (ktime_after(ktime_get(), timeout)) {
++ dev_err(cprman->dev, "timeout waiting for !BUSY\n");
++ count = 0;
++ goto out;
++ }
++ cpu_relax();
++ }
++
++ count = cprman_read(cprman, CM_TCNTCNT);
++
++ cprman_write(cprman, CM_TCNTCTL, 0);
++
++out:
++ spin_unlock(&cprman->regs_lock);
++
++ return count * 1000;
++}
++
+ static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
+ struct debugfs_reg32 *regs, size_t nregs,
+ struct dentry *dentry)
+@@ -473,6 +530,8 @@ struct bcm2835_clock_data {
+
+ bool is_vpu_clock;
+ bool is_mash_clock;
++
++ u32 tcnt_mux;
+ };
+
+ struct bcm2835_gate_data {
+@@ -1008,6 +1067,17 @@ static int bcm2835_clock_on(struct clk_h
+ CM_GATE);
+ spin_unlock(&cprman->regs_lock);
+
++ /* Debug code to measure the clock once it's turned on to see
++ * if it's ticking at the rate we expect.
++ */
++ if (data->tcnt_mux && false) {
++ dev_info(cprman->dev,
++ "clk %s: rate %ld, measure %ld\n",
++ data->name,
++ clk_hw_get_rate(hw),
++ bcm2835_measure_tcnt_mux(cprman, data->tcnt_mux));
++ }
++
+ return 0;
+ }
+
+@@ -1774,7 +1844,8 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_OTPCTL,
+ .div_reg = CM_OTPDIV,
+ .int_bits = 4,
+- .frac_bits = 0),
++ .frac_bits = 0,
++ .tcnt_mux = 6),
+ /*
+ * Used for a 1Mhz clock for the system clocksource, and also used
+ * bythe watchdog timer and the camera pulse generator.
+@@ -1808,13 +1879,15 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_H264CTL,
+ .div_reg = CM_H264DIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 1),
+ [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
+ .name = "isp",
+ .ctl_reg = CM_ISPCTL,
+ .div_reg = CM_ISPDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 2),
+
+ /*
+ * Secondary SDRAM clock. Used for low-voltage modes when the PLL
+@@ -1825,13 +1898,15 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_SDCCTL,
+ .div_reg = CM_SDCDIV,
+ .int_bits = 6,
+- .frac_bits = 0),
++ .frac_bits = 0,
++ .tcnt_mux = 3),
+ [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
+ .name = "v3d",
+ .ctl_reg = CM_V3DCTL,
+ .div_reg = CM_V3DDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 4),
+ /*
+ * VPU clock. This doesn't have an enable bit, since it drives
+ * the bus for everything else, and is special so it doesn't need
+@@ -1845,7 +1920,8 @@ static const struct bcm2835_clk_desc clk
+ .int_bits = 12,
+ .frac_bits = 8,
+ .flags = CLK_IS_CRITICAL,
+- .is_vpu_clock = true),
++ .is_vpu_clock = true,
++ .tcnt_mux = 5),
+
+ /* clocks with per parent mux */
+ [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
+@@ -1853,19 +1929,22 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_AVEOCTL,
+ .div_reg = CM_AVEODIV,
+ .int_bits = 4,
+- .frac_bits = 0),
++ .frac_bits = 0,
++ .tcnt_mux = 38),
+ [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
+ .name = "cam0",
+ .ctl_reg = CM_CAM0CTL,
+ .div_reg = CM_CAM0DIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 14),
+ [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
+ .name = "cam1",
+ .ctl_reg = CM_CAM1CTL,
+ .div_reg = CM_CAM1DIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 15),
+ [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
+ .name = "dft",
+ .ctl_reg = CM_DFTCTL,
+@@ -1877,7 +1956,8 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_DPICTL,
+ .div_reg = CM_DPIDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 17),
+
+ /* Arasan EMMC clock */
+ [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
+@@ -1885,7 +1965,8 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_EMMCCTL,
+ .div_reg = CM_EMMCDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 39),
+
+ /* General purpose (GPIO) clocks */
+ [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
+@@ -1894,7 +1975,8 @@ static const struct bcm2835_clk_desc clk
+ .div_reg = CM_GP0DIV,
+ .int_bits = 12,
+ .frac_bits = 12,
+- .is_mash_clock = true),
++ .is_mash_clock = true,
++ .tcnt_mux = 20),
+ [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
+ .name = "gp1",
+ .ctl_reg = CM_GP1CTL,
+@@ -1902,7 +1984,8 @@ static const struct bcm2835_clk_desc clk
+ .int_bits = 12,
+ .frac_bits = 12,
+ .flags = CLK_IS_CRITICAL,
+- .is_mash_clock = true),
++ .is_mash_clock = true,
++ .tcnt_mux = 21),
+ [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
+ .name = "gp2",
+ .ctl_reg = CM_GP2CTL,
+@@ -1917,40 +2000,46 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_HSMCTL,
+ .div_reg = CM_HSMDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 22),
+ [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK(
+ .name = "pcm",
+ .ctl_reg = CM_PCMCTL,
+ .div_reg = CM_PCMDIV,
+ .int_bits = 12,
+ .frac_bits = 12,
+- .is_mash_clock = true),
++ .is_mash_clock = true,
++ .tcnt_mux = 23),
+ [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
+ .name = "pwm",
+ .ctl_reg = CM_PWMCTL,
+ .div_reg = CM_PWMDIV,
+ .int_bits = 12,
+ .frac_bits = 12,
+- .is_mash_clock = true),
++ .is_mash_clock = true,
++ .tcnt_mux = 24),
+ [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
+ .name = "slim",
+ .ctl_reg = CM_SLIMCTL,
+ .div_reg = CM_SLIMDIV,
+ .int_bits = 12,
+ .frac_bits = 12,
+- .is_mash_clock = true),
++ .is_mash_clock = true,
++ .tcnt_mux = 25),
+ [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
+ .name = "smi",
+ .ctl_reg = CM_SMICTL,
+ .div_reg = CM_SMIDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 27),
+ [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
+ .name = "uart",
+ .ctl_reg = CM_UARTCTL,
+ .div_reg = CM_UARTDIV,
+ .int_bits = 10,
+- .frac_bits = 12),
++ .frac_bits = 12,
++ .tcnt_mux = 28),
+
+ /* TV encoder clock. Only operating frequency is 108Mhz. */
+ [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
+@@ -1963,7 +2052,8 @@ static const struct bcm2835_clk_desc clk
+ * Allow rate change propagation only on PLLH_AUX which is
+ * assigned index 7 in the parent array.
+ */
+- .set_rate_parent = BIT(7)),
++ .set_rate_parent = BIT(7),
++ .tcnt_mux = 29),
+
+ /* dsi clocks */
+ [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
+@@ -1971,25 +2061,29 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_DSI0ECTL,
+ .div_reg = CM_DSI0EDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 18),
+ [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
+ .name = "dsi1e",
+ .ctl_reg = CM_DSI1ECTL,
+ .div_reg = CM_DSI1EDIV,
+ .int_bits = 4,
+- .frac_bits = 8),
++ .frac_bits = 8,
++ .tcnt_mux = 19),
+ [BCM2835_CLOCK_DSI0P] = REGISTER_DSI0_CLK(
+ .name = "dsi0p",
+ .ctl_reg = CM_DSI0PCTL,
+ .div_reg = CM_DSI0PDIV,
+ .int_bits = 0,
+- .frac_bits = 0),
++ .frac_bits = 0,
++ .tcnt_mux = 12),
+ [BCM2835_CLOCK_DSI1P] = REGISTER_DSI1_CLK(
+ .name = "dsi1p",
+ .ctl_reg = CM_DSI1PCTL,
+ .div_reg = CM_DSI1PDIV,
+ .int_bits = 0,
+- .frac_bits = 0),
++ .frac_bits = 0,
++ .tcnt_mux = 13),
+
+ /* the gates */
+
diff --git a/target/linux/brcm2708/patches-4.9/0158-drm-panel-Add-support-for-the-Raspberry-Pi-7-Touchsc.patch b/target/linux/brcm2708/patches-4.9/0158-drm-panel-Add-support-for-the-Raspberry-Pi-7-Touchsc.patch
new file mode 100644
index 0000000000..027e5c07e5
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0158-drm-panel-Add-support-for-the-Raspberry-Pi-7-Touchsc.patch
@@ -0,0 +1,575 @@
+From e2d195723ec030733cdaf623c9419af5f308b230 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 26 Apr 2016 13:46:13 -0700
+Subject: [PATCH] drm/panel: Add support for the Raspberry Pi 7" Touchscreen.
+
+This driver communicates with the Atmel microcontroller for sequencing
+the poweron of the TC358762 DSI-DPI bridge and controlling the
+backlight PWM.
+
+The following lines are required in config.txt, to keep the firmware
+from trying to bash our I2C lines and steal the DSI interrupts:
+
+ disable_touchscreen=1
+ ignore_lcd=2
+ mask_gpu_interrupt1=0x1000
+
+This means that the firmware won't power on the panel at boot time (no
+rainbow) and the touchscreen input won't work. The native input
+driver for the touchscreen still needs to be written.
+
+v2: Set the same default orientation as the closed source firmware
+ used, which is the best for viewing angle.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/panel/Kconfig | 8 +
+ drivers/gpu/drm/panel/Makefile | 1 +
+ .../gpu/drm/panel/panel-raspberrypi-touchscreen.c | 514 +++++++++++++++++++++
+ 3 files changed, 523 insertions(+)
+ create mode 100644 drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+
+--- a/drivers/gpu/drm/panel/Kconfig
++++ b/drivers/gpu/drm/panel/Kconfig
+@@ -52,6 +52,14 @@ config DRM_PANEL_PANASONIC_VVX10F034N00
+ WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some
+ Xperia Z2 tablets
+
++config DRM_PANEL_RASPBERRYPI_TOUCHSCREEN
++ tristate "Raspberry Pi 7-inch touchscreen panel"
++ depends on DRM_MIPI_DSI
++ help
++ Say Y here if you want to enable support for the Raspberry
++ Pi 7" Touchscreen. To compile this driver as a module,
++ choose M here.
++
+ config DRM_PANEL_SAMSUNG_S6E8AA0
+ tristate "Samsung S6E8AA0 DSI video mode panel"
+ depends on OF
+--- a/drivers/gpu/drm/panel/Makefile
++++ b/drivers/gpu/drm/panel/Makefile
+@@ -2,6 +2,7 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-
+ obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
+ obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
+ obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
++obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o
+ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
+ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
+ obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
+--- /dev/null
++++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+@@ -0,0 +1,514 @@
++/*
++ * Copyright © 2016 Broadcom
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Portions of this file (derived from panel-simple.c) are:
++ *
++ * Copyright (C) 2013, NVIDIA Corporation. All rights reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sub license,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial portions
++ * of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ */
++
++/**
++ * DOC: Raspberry Pi 7" touchscreen panel driver.
++ *
++ * The 7" touchscreen consists of a DPI LCD panel, a Toshiba
++ * TC358762XBG DSI-DPI bridge, and an I2C-connected Atmel ATTINY88-MUR
++ * controlling power management, the LCD PWM, and the touchscreen.
++ *
++ * This driver presents this device as a MIPI DSI panel to the DRM
++ * driver, and should expose the touchscreen as a HID device.
++ */
++
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/fb.h>
++#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_graph.h>
++#include <linux/pm.h>
++
++#include <drm/drm_panel.h>
++#include <drm/drmP.h>
++#include <drm/drm_crtc.h>
++#include <drm/drm_mipi_dsi.h>
++#include <drm/drm_panel.h>
++
++/* I2C registers of the Atmel microcontroller. */
++enum REG_ADDR {
++ REG_ID = 0x80,
++ REG_PORTA, // BIT(2) for horizontal flip, BIT(3) for vertical flip
++ REG_PORTB,
++ REG_PORTC,
++ REG_PORTD,
++ REG_POWERON,
++ REG_PWM,
++ REG_DDRA,
++ REG_DDRB,
++ REG_DDRC,
++ REG_DDRD,
++ REG_TEST,
++ REG_WR_ADDRL,
++ REG_WR_ADDRH,
++ REG_READH,
++ REG_READL,
++ REG_WRITEH,
++ REG_WRITEL,
++ REG_ID2,
++};
++
++/* We only turn the PWM on or off, without varying values. */
++#define RPI_TOUCHSCREEN_MAX_BRIGHTNESS 1
++
++/* DSI D-PHY Layer Registers */
++#define D0W_DPHYCONTTX 0x0004
++#define CLW_DPHYCONTRX 0x0020
++#define D0W_DPHYCONTRX 0x0024
++#define D1W_DPHYCONTRX 0x0028
++#define COM_DPHYCONTRX 0x0038
++#define CLW_CNTRL 0x0040
++#define D0W_CNTRL 0x0044
++#define D1W_CNTRL 0x0048
++#define DFTMODE_CNTRL 0x0054
++
++/* DSI PPI Layer Registers */
++#define PPI_STARTPPI 0x0104
++#define PPI_BUSYPPI 0x0108
++#define PPI_LINEINITCNT 0x0110
++#define PPI_LPTXTIMECNT 0x0114
++//#define PPI_LANEENABLE 0x0134
++//#define PPI_TX_RX_TA 0x013C
++#define PPI_CLS_ATMR 0x0140
++#define PPI_D0S_ATMR 0x0144
++#define PPI_D1S_ATMR 0x0148
++#define PPI_D0S_CLRSIPOCOUNT 0x0164
++#define PPI_D1S_CLRSIPOCOUNT 0x0168
++#define CLS_PRE 0x0180
++#define D0S_PRE 0x0184
++#define D1S_PRE 0x0188
++#define CLS_PREP 0x01A0
++#define D0S_PREP 0x01A4
++#define D1S_PREP 0x01A8
++#define CLS_ZERO 0x01C0
++#define D0S_ZERO 0x01C4
++#define D1S_ZERO 0x01C8
++#define PPI_CLRFLG 0x01E0
++#define PPI_CLRSIPO 0x01E4
++#define HSTIMEOUT 0x01F0
++#define HSTIMEOUTENABLE 0x01F4
++
++/* DSI Protocol Layer Registers */
++#define DSI_STARTDSI 0x0204
++#define DSI_BUSYDSI 0x0208
++#define DSI_LANEENABLE 0x0210
++# define DSI_LANEENABLE_CLOCK BIT(0)
++# define DSI_LANEENABLE_D0 BIT(1)
++# define DSI_LANEENABLE_D1 BIT(2)
++
++#define DSI_LANESTATUS0 0x0214
++#define DSI_LANESTATUS1 0x0218
++#define DSI_INTSTATUS 0x0220
++#define DSI_INTMASK 0x0224
++#define DSI_INTCLR 0x0228
++#define DSI_LPTXTO 0x0230
++#define DSI_MODE 0x0260
++#define DSI_PAYLOAD0 0x0268
++#define DSI_PAYLOAD1 0x026C
++#define DSI_SHORTPKTDAT 0x0270
++#define DSI_SHORTPKTREQ 0x0274
++#define DSI_BTASTA 0x0278
++#define DSI_BTACLR 0x027C
++
++/* DSI General Registers */
++#define DSIERRCNT 0x0300
++#define DSISIGMOD 0x0304
++
++/* DSI Application Layer Registers */
++#define APLCTRL 0x0400
++#define APLSTAT 0x0404
++#define APLERR 0x0408
++#define PWRMOD 0x040C
++#define RDPKTLN 0x0410
++#define PXLFMT 0x0414
++#define MEMWRCMD 0x0418
++
++/* LCDC/DPI Host Registers */
++#define LCDCTRL 0x0420
++#define HSR 0x0424
++#define HDISPR 0x0428
++#define VSR 0x042C
++#define VDISPR 0x0430
++#define VFUEN 0x0434
++
++/* DBI-B Host Registers */
++#define DBIBCTRL 0x0440
++
++/* SPI Master Registers */
++#define SPICMR 0x0450
++#define SPITCR 0x0454
++
++/* System Controller Registers */
++#define SYSSTAT 0x0460
++#define SYSCTRL 0x0464
++#define SYSPLL1 0x0468
++#define SYSPLL2 0x046C
++#define SYSPLL3 0x0470
++#define SYSPMCTRL 0x047C
++
++/* GPIO Registers */
++#define GPIOC 0x0480
++#define GPIOO 0x0484
++#define GPIOI 0x0488
++
++/* I2C Registers */
++#define I2CCLKCTRL 0x0490
++
++/* Chip/Rev Registers */
++#define IDREG 0x04A0
++
++/* Debug Registers */
++#define WCMDQUEUE 0x0500
++#define RCMDQUEUE 0x0504
++
++struct rpi_touchscreen {
++ struct drm_panel base;
++ struct mipi_dsi_device *dsi;
++ struct i2c_client *bridge_i2c;
++
++ /* Version of the firmware on the bridge chip */
++ int atmel_ver;
++};
++
++static const struct drm_display_mode rpi_touchscreen_modes[] = {
++ {
++ /* The DSI PLL can only integer divide from the 2Ghz
++ * PLLD, giving us few choices. We pick a divide by 3
++ * as our DSI HS clock, giving us a pixel clock of
++ * that divided by 24 bits. Pad out HFP to get our
++ * panel to refresh at 60Hz, even if that doesn't
++ * match the datasheet.
++ */
++#define PIXEL_CLOCK ((2000000000 / 3) / 24)
++#define VREFRESH 60
++#define VTOTAL (480 + 7 + 2 + 21)
++#define HACT 800
++#define HSW 2
++#define HBP 46
++#define HFP ((PIXEL_CLOCK / (VTOTAL * VREFRESH)) - (HACT + HSW + HBP))
++
++ .clock = PIXEL_CLOCK / 1000,
++ .hdisplay = HACT,
++ .hsync_start = HACT + HFP,
++ .hsync_end = HACT + HFP + HSW,
++ .htotal = HACT + HFP + HSW + HBP,
++ .vdisplay = 480,
++ .vsync_start = 480 + 7,
++ .vsync_end = 480 + 7 + 2,
++ .vtotal = VTOTAL,
++ .vrefresh = 60,
++ },
++};
++
++static struct rpi_touchscreen *panel_to_ts(struct drm_panel *panel)
++{
++ return container_of(panel, struct rpi_touchscreen, base);
++}
++
++static u8 rpi_touchscreen_i2c_read(struct rpi_touchscreen *ts, u8 reg)
++{
++ return i2c_smbus_read_byte_data(ts->bridge_i2c, reg);
++}
++
++static void rpi_touchscreen_i2c_write(struct rpi_touchscreen *ts,
++ u8 reg, u8 val)
++{
++ int ret;
++
++ ret = i2c_smbus_write_byte_data(ts->bridge_i2c, reg, val);
++ if (ret)
++ dev_err(&ts->dsi->dev, "I2C write failed: %d\n", ret);
++}
++
++static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val)
++{
++#if 0
++ /* The firmware uses LP DSI transactions like this to bring up
++ * the hardware, which should be faster than using I2C to then
++ * pass to the Toshiba. However, I was unable to get it to
++ * work.
++ */
++ u8 msg[] = {
++ reg,
++ reg >> 8,
++ val,
++ val >> 8,
++ val >> 16,
++ val >> 24,
++ };
++
++ mipi_dsi_dcs_write_buffer(ts->dsi, msg, sizeof(msg));
++#else
++ rpi_touchscreen_i2c_write(ts, REG_WR_ADDRH, reg >> 8);
++ rpi_touchscreen_i2c_write(ts, REG_WR_ADDRL, reg);
++ rpi_touchscreen_i2c_write(ts, REG_WRITEH, val >> 8);
++ rpi_touchscreen_i2c_write(ts, REG_WRITEL, val);
++#endif
++
++ return 0;
++}
++
++static int rpi_touchscreen_disable(struct drm_panel *panel)
++{
++ struct rpi_touchscreen *ts = panel_to_ts(panel);
++
++ rpi_touchscreen_i2c_write(ts, REG_PWM, 0);
++
++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0);
++ udelay(1);
++
++ return 0;
++}
++
++static int rpi_touchscreen_noop(struct drm_panel *panel)
++{
++ return 0;
++}
++
++static int rpi_touchscreen_enable(struct drm_panel *panel)
++{
++ struct rpi_touchscreen *ts = panel_to_ts(panel);
++ int i;
++
++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 1);
++ /* Wait for nPWRDWN to go low to indicate poweron is done. */
++ for (i = 0; i < 100; i++) {
++ if (rpi_touchscreen_i2c_read(ts, REG_PORTB) & 1)
++ break;
++ }
++
++ rpi_touchscreen_write(ts, DSI_LANEENABLE,
++ DSI_LANEENABLE_CLOCK |
++ DSI_LANEENABLE_D0 |
++ (ts->dsi->lanes > 1 ? DSI_LANEENABLE_D1 : 0));
++ rpi_touchscreen_write(ts, PPI_D0S_CLRSIPOCOUNT, 0x05);
++ rpi_touchscreen_write(ts, PPI_D1S_CLRSIPOCOUNT, 0x05);
++ rpi_touchscreen_write(ts, PPI_D0S_ATMR, 0x00);
++ rpi_touchscreen_write(ts, PPI_D1S_ATMR, 0x00);
++ rpi_touchscreen_write(ts, PPI_LPTXTIMECNT, 0x03);
++
++ rpi_touchscreen_write(ts, SPICMR, 0x00);
++ rpi_touchscreen_write(ts, LCDCTRL, 0x00100150);
++ rpi_touchscreen_write(ts, SYSCTRL, 0x040f);
++ msleep(100);
++
++ rpi_touchscreen_write(ts, PPI_STARTPPI, 0x01);
++ rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01);
++ msleep(100);
++
++ /* Turn on the backlight. */
++ rpi_touchscreen_i2c_write(ts, REG_PWM, 255);
++
++ /* Default to the same orientation as the closed source
++ * firmware used for the panel. Runtime rotation
++ * configuration will be supported using VC4's plane
++ * orientation bits.
++ */
++ rpi_touchscreen_i2c_write(ts, REG_PORTA, BIT(2));
++
++ return 0;
++}
++
++static int rpi_touchscreen_get_modes(struct drm_panel *panel)
++{
++ struct drm_connector *connector = panel->connector;
++ struct drm_device *drm = panel->drm;
++ unsigned int i, num = 0;
++
++ for (i = 0; i < ARRAY_SIZE(rpi_touchscreen_modes); i++) {
++ const struct drm_display_mode *m = &rpi_touchscreen_modes[i];
++ struct drm_display_mode *mode;
++
++ mode = drm_mode_duplicate(drm, m);
++ if (!mode) {
++ dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
++ m->hdisplay, m->vdisplay, m->vrefresh);
++ continue;
++ }
++
++ mode->type |= DRM_MODE_TYPE_DRIVER;
++
++ if (i == 0)
++ mode->type |= DRM_MODE_TYPE_PREFERRED;
++
++ drm_mode_set_name(mode);
++
++ drm_mode_probed_add(connector, mode);
++ num++;
++ }
++
++ connector->display_info.bpc = 8;
++ connector->display_info.width_mm = 154;
++ connector->display_info.height_mm = 86;
++
++ return num;
++}
++
++static const struct drm_panel_funcs rpi_touchscreen_funcs = {
++ .disable = rpi_touchscreen_disable,
++ .unprepare = rpi_touchscreen_noop,
++ .prepare = rpi_touchscreen_noop,
++ .enable = rpi_touchscreen_enable,
++ .get_modes = rpi_touchscreen_get_modes,
++};
++
++static struct i2c_client *rpi_touchscreen_get_i2c(struct device *dev,
++ const char *name)
++{
++ struct device_node *node;
++ struct i2c_client *client;
++
++ node = of_parse_phandle(dev->of_node, name, 0);
++ if (!node)
++ return ERR_PTR(-ENODEV);
++
++ client = of_find_i2c_device_by_node(node);
++
++ of_node_put(node);
++
++ return client;
++}
++
++static int rpi_touchscreen_dsi_probe(struct mipi_dsi_device *dsi)
++{
++ struct device *dev = &dsi->dev;
++ struct rpi_touchscreen *ts;
++ int ret, ver;
++
++ ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
++ if (!ts)
++ return -ENOMEM;
++
++ dev_set_drvdata(dev, ts);
++
++ ts->dsi = dsi;
++ dsi->mode_flags = (MIPI_DSI_MODE_VIDEO |
++ MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
++ MIPI_DSI_MODE_LPM);
++ dsi->format = MIPI_DSI_FMT_RGB888;
++ dsi->lanes = 1;
++
++ ts->bridge_i2c =
++ rpi_touchscreen_get_i2c(dev, "raspberrypi,touchscreen-bridge");
++ if (IS_ERR(ts->bridge_i2c)) {
++ ret = -EPROBE_DEFER;
++ return ret;
++ }
++
++ ver = rpi_touchscreen_i2c_read(ts, REG_ID);
++ if (ver < 0) {
++ dev_err(dev, "Atmel I2C read failed: %d\n", ver);
++ return -ENODEV;
++ }
++
++ switch (ver) {
++ case 0xde:
++ ts->atmel_ver = 1;
++ break;
++ case 0xc3:
++ ts->atmel_ver = 2;
++ break;
++ default:
++ dev_err(dev, "Unknown Atmel firmware revision: 0x%02x\n", ver);
++ return -ENODEV;
++ }
++
++ /* Turn off at boot, so we can cleanly sequence powering on. */
++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0);
++
++ drm_panel_init(&ts->base);
++ ts->base.dev = dev;
++ ts->base.funcs = &rpi_touchscreen_funcs;
++
++ ret = drm_panel_add(&ts->base);
++ if (ret < 0)
++ goto err_release_bridge;
++
++ return mipi_dsi_attach(dsi);
++
++err_release_bridge:
++ put_device(&ts->bridge_i2c->dev);
++ return ret;
++}
++
++static int rpi_touchscreen_dsi_remove(struct mipi_dsi_device *dsi)
++{
++ struct device *dev = &dsi->dev;
++ struct rpi_touchscreen *ts = dev_get_drvdata(dev);
++ int ret;
++
++ ret = mipi_dsi_detach(dsi);
++ if (ret < 0) {
++ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
++ return ret;
++ }
++
++ drm_panel_detach(&ts->base);
++ drm_panel_remove(&ts->base);
++
++ put_device(&ts->bridge_i2c->dev);
++
++ return 0;
++}
++
++static void rpi_touchscreen_dsi_shutdown(struct mipi_dsi_device *dsi)
++{
++ struct device *dev = &dsi->dev;
++ struct rpi_touchscreen *ts = dev_get_drvdata(dev);
++
++ rpi_touchscreen_i2c_write(ts, REG_POWERON, 0);
++}
++
++static const struct of_device_id rpi_touchscreen_of_match[] = {
++ { .compatible = "raspberrypi,touchscreen" },
++ { } /* sentinel */
++};
++MODULE_DEVICE_TABLE(of, rpi_touchscreen_of_match);
++
++static struct mipi_dsi_driver rpi_touchscreen_driver = {
++ .driver = {
++ .name = "raspberrypi-touchscreen",
++ .of_match_table = rpi_touchscreen_of_match,
++ },
++ .probe = rpi_touchscreen_dsi_probe,
++ .remove = rpi_touchscreen_dsi_remove,
++ .shutdown = rpi_touchscreen_dsi_shutdown,
++};
++module_mipi_dsi_driver(rpi_touchscreen_driver);
++
++MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
++MODULE_DESCRIPTION("Raspberry Pi 7-inch touchscreen driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/brcm2708/patches-4.9/0159-BCM270X-Add-the-DSI-panel-to-the-defconfig.patch b/target/linux/brcm2708/patches-4.9/0159-BCM270X-Add-the-DSI-panel-to-the-defconfig.patch
new file mode 100644
index 0000000000..1ba605bc39
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0159-BCM270X-Add-the-DSI-panel-to-the-defconfig.patch
@@ -0,0 +1,45 @@
+From 22f86bb2d3cb5275877fc4784d2f6c4f5cc660e9 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 2 Jun 2016 12:29:45 -0700
+Subject: [PATCH] BCM270X: Add the DSI panel to the defconfig.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/configs/bcm2709_defconfig | 2 ++
+ arch/arm/configs/bcmrpi_defconfig | 2 ++
+ arch/arm64/configs/bcmrpi3_defconfig | 2 ++
+ 3 files changed, 6 insertions(+)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -833,6 +833,8 @@ CONFIG_VIDEO_OV7640=m
+ CONFIG_VIDEO_MT9V011=m
+ CONFIG_DRM=m
+ CONFIG_DRM_LOAD_EDID_FIRMWARE=y
++CONFIG_DRM_PANEL_SIMPLE=m
++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
+ CONFIG_DRM_UDL=m
+ CONFIG_DRM_VC4=m
+ CONFIG_FB=y
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -827,6 +827,8 @@ CONFIG_VIDEO_OV7640=m
+ CONFIG_VIDEO_MT9V011=m
+ CONFIG_DRM=m
+ CONFIG_DRM_LOAD_EDID_FIRMWARE=y
++CONFIG_DRM_PANEL_SIMPLE=m
++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
+ CONFIG_DRM_UDL=m
+ CONFIG_DRM_VC4=m
+ CONFIG_FB=y
+--- a/arch/arm64/configs/bcmrpi3_defconfig
++++ b/arch/arm64/configs/bcmrpi3_defconfig
+@@ -816,6 +816,8 @@ CONFIG_VIDEO_OV7640=m
+ CONFIG_VIDEO_MT9V011=m
+ CONFIG_DRM=m
+ CONFIG_DRM_LOAD_EDID_FIRMWARE=y
++CONFIG_DRM_PANEL_SIMPLE=m
++CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
+ CONFIG_DRM_UDL=m
+ CONFIG_DRM_VC4=m
+ CONFIG_FB=y
diff --git a/target/linux/brcm2708/patches-4.9/0160-ARM-bcm2835-dt-Add-the-DSI-module-nodes-and-clocks.patch b/target/linux/brcm2708/patches-4.9/0160-ARM-bcm2835-dt-Add-the-DSI-module-nodes-and-clocks.patch
new file mode 100644
index 0000000000..444c287eed
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0160-ARM-bcm2835-dt-Add-the-DSI-module-nodes-and-clocks.patch
@@ -0,0 +1,101 @@
+From fc25cd03ca1c696dacb74d2006c0f176ce800566 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 13 Dec 2016 15:15:10 -0800
+Subject: [PATCH] ARM: bcm2835: dt: Add the DSI module nodes and clocks.
+
+The modules stay disabled by default, and if you want to enable DSI
+you'll need an overlay that connects a panel to it.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 8 +++++++
+ arch/arm/boot/dts/bcm283x.dtsi | 49 +++++++++++++++++++++++++++++++++++---
+ 2 files changed, 54 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -84,3 +84,11 @@
+ power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+ status = "okay";
+ };
++
++&dsi0 {
++ power-domains = <&power RPI_POWER_DOMAIN_DSI0>;
++};
++
++&dsi1 {
++ power-domains = <&power RPI_POWER_DOMAIN_DSI1>;
++};
+--- a/arch/arm/boot/dts/bcm283x.dtsi
++++ b/arch/arm/boot/dts/bcm283x.dtsi
+@@ -93,10 +93,13 @@
+ #clock-cells = <1>;
+ reg = <0x7e101000 0x2000>;
+
+- /* CPRMAN derives everything from the platform's
+- * oscillator.
++ /* CPRMAN derives almost everything from the
++ * platform's oscillator. However, the DSI
++ * pixel clocks come from the DSI analog PHY.
+ */
+- clocks = <&clk_osc>;
++ clocks = <&clk_osc>,
++ <&dsi0 0>, <&dsi0 1>, <&dsi0 2>,
++ <&dsi1 0>, <&dsi1 1>, <&dsi1 2>;
+ };
+
+ rng@7e104000 {
+@@ -188,6 +191,26 @@
+ interrupts = <2 14>; /* pwa1 */
+ };
+
++ dsi0: dsi@7e209000 {
++ compatible = "brcm,bcm2835-dsi0";
++ reg = <0x7e209000 0x78>;
++ interrupts = <2 4>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #clock-cells = <1>;
++
++ clocks = <&clocks BCM2835_PLLA_DSI0>,
++ <&clocks BCM2835_CLOCK_DSI0E>,
++ <&clocks BCM2835_CLOCK_DSI0P>;
++ clock-names = "phy", "escape", "pixel";
++
++ clock-output-names = "dsi0_byte",
++ "dsi0_ddr2",
++ "dsi0_ddr";
++
++ status = "disabled";
++ };
++
+ aux: aux@0x7e215000 {
+ compatible = "brcm,bcm2835-aux";
+ #clock-cells = <1>;
+@@ -247,6 +270,26 @@
+ interrupts = <2 1>;
+ };
+
++ dsi1: dsi@7e700000 {
++ compatible = "brcm,bcm2835-dsi1";
++ reg = <0x7e700000 0x8c>;
++ interrupts = <2 12>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #clock-cells = <1>;
++
++ clocks = <&clocks BCM2835_PLLD_DSI1>,
++ <&clocks BCM2835_CLOCK_DSI1E>,
++ <&clocks BCM2835_CLOCK_DSI1P>;
++ clock-names = "phy", "escape", "pixel";
++
++ clock-output-names = "dsi1_byte",
++ "dsi1_ddr2",
++ "dsi1_ddr";
++
++ status = "disabled";
++ };
++
+ i2c1: i2c@7e804000 {
+ compatible = "brcm,bcm2835-i2c";
+ reg = <0x7e804000 0x1000>;
diff --git a/target/linux/brcm2708/patches-4.9/0161-BCM270X-Enable-the-DSI-panel-node-in-the-VC4-overlay.patch b/target/linux/brcm2708/patches-4.9/0161-BCM270X-Enable-the-DSI-panel-node-in-the-VC4-overlay.patch
new file mode 100644
index 0000000000..3d65f5e269
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0161-BCM270X-Enable-the-DSI-panel-node-in-the-VC4-overlay.patch
@@ -0,0 +1,138 @@
+From 2c62d430b6b3c20867e55465e0557a1543088f09 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 2 Jun 2016 15:09:35 -0700
+Subject: [PATCH] BCM270X: Enable the DSI panel node in the VC4 overlay.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 5 ++++
+ arch/arm/boot/dts/bcm2708-rpi-b.dts | 5 ++++
+ arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 5 ++++
+ arch/arm/boot/dts/bcm270x.dtsi | 27 ++++++++++++++++++++++
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 5 ++++
+ arch/arm/boot/dts/bcm2710.dtsi | 1 -
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 22 ++++++++++++++++++
+ 7 files changed, 69 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
+@@ -154,3 +154,8 @@
+ sd_debug = <&sdhost>,"brcm,debug";
+ };
+ };
++
++&i2c_dsi {
++ gpios = <&gpio 28 0
++ &gpio 29 0>;
++};
+--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
+@@ -144,3 +144,8 @@
+ sd_debug = <&sdhost>,"brcm,debug";
+ };
+ };
++
++&i2c_dsi {
++ gpios = <&gpio 2 0
++ &gpio 3 0>;
++};
+--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
+@@ -154,3 +154,8 @@
+ sd_debug = <&sdhost>,"brcm,debug";
+ };
+ };
++
++&i2c_dsi {
++ gpios = <&gpio 28 0
++ &gpio 29 0>;
++};
+--- a/arch/arm/boot/dts/bcm270x.dtsi
++++ b/arch/arm/boot/dts/bcm270x.dtsi
+@@ -137,6 +137,29 @@
+ /* Add alias */
+ status = "disabled";
+ };
++
++ i2c_dsi: i2cdsi {
++ /* We have to use i2c-gpio because the
++ * firmware is also polling another device
++ * using the only hardware I2C bus that could
++ * connect to these pins.
++ */
++ compatible = "i2c-gpio";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pitouchscreen_bridge: bridge@45 {
++ compatible = "raspberrypi,touchscreen-bridge-i2c";
++ reg = <0x45>;
++ };
++
++ pitouchscreen_touch: bridge@38 {
++ compatible = "raspberrypi,touchscreen-ts-i2c";
++ reg = <0x38>;
++ };
++ };
++
+ };
+
+ vdd_5v0_reg: fixedregulator_5v0 {
+@@ -155,3 +178,7 @@
+ regulator-always-on;
+ };
+ };
++
++&dsi1 {
++ power-domains = <&power RPI_POWER_DOMAIN_DSI1>;
++};
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -201,3 +201,8 @@
+ sd_debug = <&sdhost>,"brcm,debug";
+ };
+ };
++
++&i2c_dsi {
++ gpios = <&gpio 44 0
++ &gpio 45 0>;
++};
+--- a/arch/arm/boot/dts/bcm2710.dtsi
++++ b/arch/arm/boot/dts/bcm2710.dtsi
+@@ -145,4 +145,3 @@
+ interrupt-parent = <&local_intc>;
+ interrupts = <8>;
+ };
+-
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
+@@ -126,6 +126,28 @@
+ };
+ };
+
++ fragment@16 {
++ target = <&dsi1>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ pitouchscreen: panel@0 {
++ compatible = "raspberrypi,touchscreen";
++ reg = <0>;
++ raspberrypi,touchscreen-bridge = <&pitouchscreen_bridge>;
++ };
++ };
++ };
++
++ fragment@17 {
++ target = <&i2c_dsi>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
+ __overrides__ {
+ cma-256 = <0>,"+0-1-2-3-4";
+ cma-192 = <0>,"-0+1-2-3-4";
diff --git a/target/linux/brcm2708/patches-4.9/0162-drm-vc4-Fix-termination-of-the-initial-scan-for-bran.patch b/target/linux/brcm2708/patches-4.9/0162-drm-vc4-Fix-termination-of-the-initial-scan-for-bran.patch
new file mode 100644
index 0000000000..3326dca659
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0162-drm-vc4-Fix-termination-of-the-initial-scan-for-bran.patch
@@ -0,0 +1,68 @@
+From 57b0774967d7ea8d4173f82387100a84e4ba05d8 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 20 Oct 2016 16:48:12 -0700
+Subject: [PATCH] drm/vc4: Fix termination of the initial scan for branch
+ targets.
+
+The loop is scanning until the original max_ip (size of the BO), but
+we want to not examine any code after the PROG_END's delay slots.
+There was a block trying to do that, except that we had some early
+continue statements if the signal wasn't a PROG_END or a BRANCH.
+
+The failure mode would be that a valid shader is rejected because some
+undefined memory after the PROG_END slots is parsed as a branch and
+the rest of its setup is illegal. I haven't seen this in the wild,
+but valgrind was complaining when about this up in the userland
+simulator mode.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 457e67a728696c4f8e6423c64e93def50530db9a)
+---
+ drivers/gpu/drm/vc4/vc4_validate_shaders.c | 19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c
++++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
+@@ -608,9 +608,7 @@ static bool
+ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
+ {
+ uint32_t max_branch_target = 0;
+- bool found_shader_end = false;
+ int ip;
+- int shader_end_ip = 0;
+ int last_branch = -2;
+
+ for (ip = 0; ip < validation_state->max_ip; ip++) {
+@@ -621,8 +619,13 @@ vc4_validate_branches(struct vc4_shader_
+ uint32_t branch_target_ip;
+
+ if (sig == QPU_SIG_PROG_END) {
+- shader_end_ip = ip;
+- found_shader_end = true;
++ /* There are two delay slots after program end is
++ * signaled that are still executed, then we're
++ * finished. validation_state->max_ip is the
++ * instruction after the last valid instruction in the
++ * program.
++ */
++ validation_state->max_ip = ip + 3;
+ continue;
+ }
+
+@@ -676,15 +679,9 @@ vc4_validate_branches(struct vc4_shader_
+ }
+ set_bit(after_delay_ip, validation_state->branch_targets);
+ max_branch_target = max(max_branch_target, after_delay_ip);
+-
+- /* There are two delay slots after program end is signaled
+- * that are still executed, then we're finished.
+- */
+- if (found_shader_end && ip == shader_end_ip + 2)
+- break;
+ }
+
+- if (max_branch_target > shader_end_ip) {
++ if (max_branch_target > validation_state->max_ip - 3) {
+ DRM_ERROR("Branch landed after QPU_SIG_PROG_END");
+ return false;
+ }
diff --git a/target/linux/brcm2708/patches-4.9/0163-drm-vc4-Add-support-for-rendering-with-ETC1-textures.patch b/target/linux/brcm2708/patches-4.9/0163-drm-vc4-Add-support-for-rendering-with-ETC1-textures.patch
new file mode 100644
index 0000000000..2b81578768
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0163-drm-vc4-Add-support-for-rendering-with-ETC1-textures.patch
@@ -0,0 +1,55 @@
+From 4b1b99ebbada744ef72af56b022492609feb9bba Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 3 Nov 2016 18:53:10 -0700
+Subject: [PATCH] drm/vc4: Add support for rendering with ETC1 textures.
+
+The validation for it ends up being quite simple, but I hadn't got
+around to it before merging the driver. For backwards compatibility,
+we also need to add a flag so that the userspace GL driver can easily
+tell if the kernel will allow ETC1 textures (on an old kernel, it will
+continue to convert to RGBA8)
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 7154d76fedf549607afbc0d13db9aaf02da5cebf)
+---
+ drivers/gpu/drm/vc4/vc4_drv.c | 1 +
+ drivers/gpu/drm/vc4/vc4_validate.c | 7 +++++++
+ include/uapi/drm/vc4_drm.h | 1 +
+ 3 files changed, 9 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -78,6 +78,7 @@ static int vc4_get_param_ioctl(struct dr
+ pm_runtime_put(&vc4->v3d->pdev->dev);
+ break;
+ case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
++ case DRM_VC4_PARAM_SUPPORTS_ETC1:
+ args->value = true;
+ break;
+ default:
+--- a/drivers/gpu/drm/vc4/vc4_validate.c
++++ b/drivers/gpu/drm/vc4/vc4_validate.c
+@@ -644,6 +644,13 @@ reloc_tex(struct vc4_exec_info *exec,
+ cpp = 1;
+ break;
+ case VC4_TEXTURE_TYPE_ETC1:
++ /* ETC1 is arranged as 64-bit blocks, where each block is 4x4
++ * pixels.
++ */
++ cpp = 8;
++ width = (width + 3) >> 2;
++ height = (height + 3) >> 2;
++ break;
+ case VC4_TEXTURE_TYPE_BW1:
+ case VC4_TEXTURE_TYPE_A4:
+ case VC4_TEXTURE_TYPE_A1:
+--- a/include/uapi/drm/vc4_drm.h
++++ b/include/uapi/drm/vc4_drm.h
+@@ -286,6 +286,7 @@ struct drm_vc4_get_hang_state {
+ #define DRM_VC4_PARAM_V3D_IDENT1 1
+ #define DRM_VC4_PARAM_V3D_IDENT2 2
+ #define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
++#define DRM_VC4_PARAM_SUPPORTS_ETC1 4
+
+ struct drm_vc4_get_param {
+ __u32 param;
diff --git a/target/linux/brcm2708/patches-4.9/0164-drm-vc4-Use-runtime-autosuspend-to-avoid-thrashing-V.patch b/target/linux/brcm2708/patches-4.9/0164-drm-vc4-Use-runtime-autosuspend-to-avoid-thrashing-V.patch
new file mode 100644
index 0000000000..f6d738d941
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0164-drm-vc4-Use-runtime-autosuspend-to-avoid-thrashing-V.patch
@@ -0,0 +1,78 @@
+From 936dc8b00ccd5072c5d610b97199402275bfdf26 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 4 Nov 2016 15:58:38 -0700
+Subject: [PATCH] drm/vc4: Use runtime autosuspend to avoid thrashing V3D power
+ state.
+
+The pm_runtime_put() we were using immediately released power on the
+device, which meant that we were generally turning the device off and
+on once per frame. In many profiles I've looked at, that added up to
+about 1% of CPU time, but this could get worse in the case of frequent
+rendering and readback (as may happen in X rendering). By keeping the
+device on until we've been idle for a couple of frames, we drop the
+overhead of runtime PM down to sub-.1%.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 3a62234680d86efa0239665ed8a0e908f1aef147)
+---
+ drivers/gpu/drm/vc4/vc4_drv.c | 9 ++++++---
+ drivers/gpu/drm/vc4/vc4_gem.c | 6 ++++--
+ drivers/gpu/drm/vc4/vc4_v3d.c | 2 ++
+ 3 files changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -61,21 +61,24 @@ static int vc4_get_param_ioctl(struct dr
+ if (ret < 0)
+ return ret;
+ args->value = V3D_READ(V3D_IDENT0);
+- pm_runtime_put(&vc4->v3d->pdev->dev);
++ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
++ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
+ break;
+ case DRM_VC4_PARAM_V3D_IDENT1:
+ ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+ if (ret < 0)
+ return ret;
+ args->value = V3D_READ(V3D_IDENT1);
+- pm_runtime_put(&vc4->v3d->pdev->dev);
++ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
++ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
+ break;
+ case DRM_VC4_PARAM_V3D_IDENT2:
+ ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
+ if (ret < 0)
+ return ret;
+ args->value = V3D_READ(V3D_IDENT2);
+- pm_runtime_put(&vc4->v3d->pdev->dev);
++ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
++ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
+ break;
+ case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
+ case DRM_VC4_PARAM_SUPPORTS_ETC1:
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -711,8 +711,10 @@ vc4_complete_exec(struct drm_device *dev
+ }
+
+ mutex_lock(&vc4->power_lock);
+- if (--vc4->power_refcount == 0)
+- pm_runtime_put(&vc4->v3d->pdev->dev);
++ if (--vc4->power_refcount == 0) {
++ pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
++ pm_runtime_put_autosuspend(&vc4->v3d->pdev->dev);
++ }
+ mutex_unlock(&vc4->power_lock);
+
+ kfree(exec);
+--- a/drivers/gpu/drm/vc4/vc4_v3d.c
++++ b/drivers/gpu/drm/vc4/vc4_v3d.c
+@@ -222,6 +222,8 @@ static int vc4_v3d_bind(struct device *d
+ return ret;
+ }
+
++ pm_runtime_use_autosuspend(dev);
++ pm_runtime_set_autosuspend_delay(dev, 40); /* a little over 2 frames. */
+ pm_runtime_enable(dev);
+
+ return 0;
diff --git a/target/linux/brcm2708/patches-4.9/0165-drm-vc4-Add-fragment-shader-threading-support.patch b/target/linux/brcm2708/patches-4.9/0165-drm-vc4-Add-fragment-shader-threading-support.patch
new file mode 100644
index 0000000000..ea0f4f1177
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0165-drm-vc4-Add-fragment-shader-threading-support.patch
@@ -0,0 +1,228 @@
+From 8f5722ac3e42a33345bfd82b7ad6a153134a4239 Mon Sep 17 00:00:00 2001
+From: Jonas Pfeil <pfeiljonas@gmx.de>
+Date: Tue, 8 Nov 2016 00:18:39 +0100
+Subject: [PATCH] drm/vc4: Add fragment shader threading support
+
+FS threading brings performance improvements of 0-20% in glmark2.
+
+The validation code checks for thread switch signals and ensures that
+the registers of the other thread are not touched, and that our clamps
+are not live across thread switches. It also checks that the
+threading and branching instructions do not interfere.
+
+(Original patch by Jonas, changes by anholt for style cleanup,
+removing validation the kernel doesn't need to do, and adding the flag
+for userspace).
+
+v2: Minor style fixes from checkpatch.
+
+Signed-off-by: Jonas Pfeil <pfeiljonas@gmx.de>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit c778cc5df944291dcdb1ca7a6bb781fbc22550c5)
+---
+ drivers/gpu/drm/vc4/vc4_drv.c | 1 +
+ drivers/gpu/drm/vc4/vc4_drv.h | 2 +
+ drivers/gpu/drm/vc4/vc4_validate.c | 17 +++++---
+ drivers/gpu/drm/vc4/vc4_validate_shaders.c | 63 ++++++++++++++++++++++++++++++
+ include/uapi/drm/vc4_drm.h | 1 +
+ 5 files changed, 79 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -82,6 +82,7 @@ static int vc4_get_param_ioctl(struct dr
+ break;
+ case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
+ case DRM_VC4_PARAM_SUPPORTS_ETC1:
++ case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
+ args->value = true;
+ break;
+ default:
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -384,6 +384,8 @@ struct vc4_validated_shader_info {
+
+ uint32_t num_uniform_addr_offsets;
+ uint32_t *uniform_addr_offsets;
++
++ bool is_threaded;
+ };
+
+ /**
+--- a/drivers/gpu/drm/vc4/vc4_validate.c
++++ b/drivers/gpu/drm/vc4/vc4_validate.c
+@@ -789,11 +789,6 @@ validate_gl_shader_rec(struct drm_device
+ exec->shader_rec_v += roundup(packet_size, 16);
+ exec->shader_rec_size -= packet_size;
+
+- if (!(*(uint16_t *)pkt_u & VC4_SHADER_FLAG_FS_SINGLE_THREAD)) {
+- DRM_ERROR("Multi-threaded fragment shaders not supported.\n");
+- return -EINVAL;
+- }
+-
+ for (i = 0; i < shader_reloc_count; i++) {
+ if (src_handles[i] > exec->bo_count) {
+ DRM_ERROR("Shader handle %d too big\n", src_handles[i]);
+@@ -810,6 +805,18 @@ validate_gl_shader_rec(struct drm_device
+ return -EINVAL;
+ }
+
++ if (((*(uint16_t *)pkt_u & VC4_SHADER_FLAG_FS_SINGLE_THREAD) == 0) !=
++ to_vc4_bo(&bo[0]->base)->validated_shader->is_threaded) {
++ DRM_ERROR("Thread mode of CL and FS do not match\n");
++ return -EINVAL;
++ }
++
++ if (to_vc4_bo(&bo[1]->base)->validated_shader->is_threaded ||
++ to_vc4_bo(&bo[2]->base)->validated_shader->is_threaded) {
++ DRM_ERROR("cs and vs cannot be threaded\n");
++ return -EINVAL;
++ }
++
+ for (i = 0; i < shader_reloc_count; i++) {
+ struct vc4_validated_shader_info *validated_shader;
+ uint32_t o = shader_reloc_offsets[i];
+--- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c
++++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
+@@ -83,6 +83,13 @@ struct vc4_shader_validation_state {
+ * basic blocks.
+ */
+ bool needs_uniform_address_for_loop;
++
++ /* Set when we find an instruction writing the top half of the
++ * register files. If we allowed writing the unusable regs in
++ * a threaded shader, then the other shader running on our
++ * QPU's clamp validation would be invalid.
++ */
++ bool all_registers_used;
+ };
+
+ static uint32_t
+@@ -119,6 +126,13 @@ raddr_add_a_to_live_reg_index(uint64_t i
+ }
+
+ static bool
++live_reg_is_upper_half(uint32_t lri)
++{
++ return (lri >= 16 && lri < 32) ||
++ (lri >= 32 + 16 && lri < 32 + 32);
++}
++
++static bool
+ is_tmu_submit(uint32_t waddr)
+ {
+ return (waddr == QPU_W_TMU0_S ||
+@@ -390,6 +404,9 @@ check_reg_write(struct vc4_validated_sha
+ } else {
+ validation_state->live_immediates[lri] = ~0;
+ }
++
++ if (live_reg_is_upper_half(lri))
++ validation_state->all_registers_used = true;
+ }
+
+ switch (waddr) {
+@@ -598,6 +615,11 @@ check_instruction_reads(struct vc4_valid
+ }
+ }
+
++ if ((raddr_a >= 16 && raddr_a < 32) ||
++ (raddr_b >= 16 && raddr_b < 32 && sig != QPU_SIG_SMALL_IMM)) {
++ validation_state->all_registers_used = true;
++ }
++
+ return true;
+ }
+
+@@ -753,6 +775,7 @@ vc4_validate_shader(struct drm_gem_cma_o
+ {
+ bool found_shader_end = false;
+ int shader_end_ip = 0;
++ uint32_t last_thread_switch_ip = -3;
+ uint32_t ip;
+ struct vc4_validated_shader_info *validated_shader = NULL;
+ struct vc4_shader_validation_state validation_state;
+@@ -785,6 +808,17 @@ vc4_validate_shader(struct drm_gem_cma_o
+ if (!vc4_handle_branch_target(&validation_state))
+ goto fail;
+
++ if (ip == last_thread_switch_ip + 3) {
++ /* Reset r0-r3 live clamp data */
++ int i;
++
++ for (i = 64; i < LIVE_REG_COUNT; i++) {
++ validation_state.live_min_clamp_offsets[i] = ~0;
++ validation_state.live_max_clamp_regs[i] = false;
++ validation_state.live_immediates[i] = ~0;
++ }
++ }
++
+ switch (sig) {
+ case QPU_SIG_NONE:
+ case QPU_SIG_WAIT_FOR_SCOREBOARD:
+@@ -794,6 +828,8 @@ vc4_validate_shader(struct drm_gem_cma_o
+ case QPU_SIG_LOAD_TMU1:
+ case QPU_SIG_PROG_END:
+ case QPU_SIG_SMALL_IMM:
++ case QPU_SIG_THREAD_SWITCH:
++ case QPU_SIG_LAST_THREAD_SWITCH:
+ if (!check_instruction_writes(validated_shader,
+ &validation_state)) {
+ DRM_ERROR("Bad write at ip %d\n", ip);
+@@ -809,6 +845,18 @@ vc4_validate_shader(struct drm_gem_cma_o
+ shader_end_ip = ip;
+ }
+
++ if (sig == QPU_SIG_THREAD_SWITCH ||
++ sig == QPU_SIG_LAST_THREAD_SWITCH) {
++ validated_shader->is_threaded = true;
++
++ if (ip < last_thread_switch_ip + 3) {
++ DRM_ERROR("Thread switch too soon after "
++ "last switch at ip %d\n", ip);
++ goto fail;
++ }
++ last_thread_switch_ip = ip;
++ }
++
+ break;
+
+ case QPU_SIG_LOAD_IMM:
+@@ -823,6 +871,13 @@ vc4_validate_shader(struct drm_gem_cma_o
+ if (!check_branch(inst, validated_shader,
+ &validation_state, ip))
+ goto fail;
++
++ if (ip < last_thread_switch_ip + 3) {
++ DRM_ERROR("Branch in thread switch at ip %d",
++ ip);
++ goto fail;
++ }
++
+ break;
+ default:
+ DRM_ERROR("Unsupported QPU signal %d at "
+@@ -844,6 +899,14 @@ vc4_validate_shader(struct drm_gem_cma_o
+ goto fail;
+ }
+
++ /* Might corrupt other thread */
++ if (validated_shader->is_threaded &&
++ validation_state.all_registers_used) {
++ DRM_ERROR("Shader uses threading, but uses the upper "
++ "half of the registers, too\n");
++ goto fail;
++ }
++
+ /* If we did a backwards branch and we haven't emitted a uniforms
+ * reset since then, we still need the uniforms stream to have the
+ * uniforms address available so that the backwards branch can do its
+--- a/include/uapi/drm/vc4_drm.h
++++ b/include/uapi/drm/vc4_drm.h
+@@ -287,6 +287,7 @@ struct drm_vc4_get_hang_state {
+ #define DRM_VC4_PARAM_V3D_IDENT2 2
+ #define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
+ #define DRM_VC4_PARAM_SUPPORTS_ETC1 4
++#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
+
+ struct drm_vc4_get_param {
+ __u32 param;
diff --git a/target/linux/brcm2708/patches-4.9/0166-drm-vc4-Fix-race-between-page-flip-completion-event-.patch b/target/linux/brcm2708/patches-4.9/0166-drm-vc4-Fix-race-between-page-flip-completion-event-.patch
new file mode 100644
index 0000000000..3c66fefafd
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0166-drm-vc4-Fix-race-between-page-flip-completion-event-.patch
@@ -0,0 +1,93 @@
+From d7f32f81cf7579ac7d13127db88e789ea864824c Mon Sep 17 00:00:00 2001
+From: Derek Foreman <derekf@osg.samsung.com>
+Date: Thu, 24 Nov 2016 12:11:55 -0600
+Subject: [PATCH] drm/vc4: Fix race between page flip completion event and
+ clean-up
+
+There was a small window where a userspace program could submit
+a pageflip after receiving a pageflip completion event yet still
+receive EBUSY.
+
+Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+Reviewed-by: Daniel Stone <daniels@collabora.com>
+(cherry picked from commit 26fc78f6fef39b9d7a15def5e7e9826ff68303f4)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 8 ++++++++
+ drivers/gpu/drm/vc4/vc4_drv.h | 1 +
+ drivers/gpu/drm/vc4/vc4_kms.c | 33 +++++++++++++++++++++++++--------
+ 3 files changed, 34 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -682,6 +682,14 @@ void vc4_disable_vblank(struct drm_devic
+ CRTC_WRITE(PV_INTEN, 0);
+ }
+
++/* Must be called with the event lock held */
++bool vc4_event_pending(struct drm_crtc *crtc)
++{
++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
++
++ return !!vc4_crtc->event;
++}
++
+ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
+ {
+ struct drm_crtc *crtc = &vc4_crtc->base;
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -445,6 +445,7 @@ int vc4_bo_stats_debugfs(struct seq_file
+ extern struct platform_driver vc4_crtc_driver;
+ int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id);
+ void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id);
++bool vc4_event_pending(struct drm_crtc *crtc);
+ int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
+ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
+ unsigned int flags, int *vpos, int *hpos,
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -119,17 +119,34 @@ static int vc4_atomic_commit(struct drm_
+
+ /* Make sure that any outstanding modesets have finished. */
+ if (nonblock) {
+- ret = down_trylock(&vc4->async_modeset);
+- if (ret) {
++ struct drm_crtc *crtc;
++ struct drm_crtc_state *crtc_state;
++ unsigned long flags;
++ bool busy = false;
++
++ /*
++ * If there's an undispatched event to send then we're
++ * obviously still busy. If there isn't, then we can
++ * unconditionally wait for the semaphore because it
++ * shouldn't be contended (for long).
++ *
++ * This is to prevent a race where queuing a new flip
++ * from userspace immediately on receipt of an event
++ * beats our clean-up and returns EBUSY.
++ */
++ spin_lock_irqsave(&dev->event_lock, flags);
++ for_each_crtc_in_state(state, crtc, crtc_state, i)
++ busy |= vc4_event_pending(crtc);
++ spin_unlock_irqrestore(&dev->event_lock, flags);
++ if (busy) {
+ kfree(c);
+ return -EBUSY;
+ }
+- } else {
+- ret = down_interruptible(&vc4->async_modeset);
+- if (ret) {
+- kfree(c);
+- return ret;
+- }
++ }
++ ret = down_interruptible(&vc4->async_modeset);
++ if (ret) {
++ kfree(c);
++ return ret;
+ }
+
+ ret = drm_atomic_helper_prepare_planes(dev, state);
diff --git a/target/linux/brcm2708/patches-4.9/0167-drm-vc4-Fix-clock_select-setting-for-the-VEC-encoder.patch b/target/linux/brcm2708/patches-4.9/0167-drm-vc4-Fix-clock_select-setting-for-the-VEC-encoder.patch
new file mode 100644
index 0000000000..c2499c130a
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0167-drm-vc4-Fix-clock_select-setting-for-the-VEC-encoder.patch
@@ -0,0 +1,113 @@
+From 3b162fdf85d89829d58bbee2d7d79987aceaa595 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 2 Dec 2016 14:48:07 +0100
+Subject: [PATCH] drm/vc4: Fix ->clock_select setting for the VEC encoder
+
+PV_CONTROL_CLK_SELECT_VEC is actually 2 and not 0. Fix the definition and
+rework the vc4_set_crtc_possible_masks() to cover the full range of the
+PV_CONTROL_CLK_SELECT field.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit ab8df60e3a3b68420d0d4477c5f07c00fbfb078b)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 38 +++++++++++++++++++++++---------------
+ drivers/gpu/drm/vc4/vc4_drv.h | 1 +
+ drivers/gpu/drm/vc4/vc4_regs.h | 3 ++-
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -83,8 +83,7 @@ struct vc4_crtc_data {
+ /* Which channel of the HVS this pixelvalve sources from. */
+ int hvs_channel;
+
+- enum vc4_encoder_type encoder0_type;
+- enum vc4_encoder_type encoder1_type;
++ enum vc4_encoder_type encoder_types[4];
+ };
+
+ #define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
+@@ -880,20 +879,26 @@ static const struct drm_crtc_helper_func
+
+ static const struct vc4_crtc_data pv0_data = {
+ .hvs_channel = 0,
+- .encoder0_type = VC4_ENCODER_TYPE_DSI0,
+- .encoder1_type = VC4_ENCODER_TYPE_DPI,
++ .encoder_types = {
++ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
++ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
++ },
+ };
+
+ static const struct vc4_crtc_data pv1_data = {
+ .hvs_channel = 2,
+- .encoder0_type = VC4_ENCODER_TYPE_DSI1,
+- .encoder1_type = VC4_ENCODER_TYPE_SMI,
++ .encoder_types = {
++ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
++ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
++ },
+ };
+
+ static const struct vc4_crtc_data pv2_data = {
+ .hvs_channel = 1,
+- .encoder0_type = VC4_ENCODER_TYPE_VEC,
+- .encoder1_type = VC4_ENCODER_TYPE_HDMI,
++ .encoder_types = {
++ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI,
++ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
++ },
+ };
+
+ static const struct of_device_id vc4_crtc_dt_match[] = {
+@@ -907,17 +912,20 @@ static void vc4_set_crtc_possible_masks(
+ struct drm_crtc *crtc)
+ {
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
++ const struct vc4_crtc_data *crtc_data = vc4_crtc->data;
++ const enum vc4_encoder_type *encoder_types = crtc_data->encoder_types;
+ struct drm_encoder *encoder;
+
+ drm_for_each_encoder(encoder, drm) {
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
++ int i;
+
+- if (vc4_encoder->type == vc4_crtc->data->encoder0_type) {
+- vc4_encoder->clock_select = 0;
+- encoder->possible_crtcs |= drm_crtc_mask(crtc);
+- } else if (vc4_encoder->type == vc4_crtc->data->encoder1_type) {
+- vc4_encoder->clock_select = 1;
+- encoder->possible_crtcs |= drm_crtc_mask(crtc);
++ for (i = 0; i < ARRAY_SIZE(crtc_data->encoder_types); i++) {
++ if (vc4_encoder->type == encoder_types[i]) {
++ vc4_encoder->clock_select = i;
++ encoder->possible_crtcs |= drm_crtc_mask(crtc);
++ break;
++ }
+ }
+ }
+ }
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -197,6 +197,7 @@ to_vc4_plane(struct drm_plane *plane)
+ }
+
+ enum vc4_encoder_type {
++ VC4_ENCODER_TYPE_NONE,
+ VC4_ENCODER_TYPE_HDMI,
+ VC4_ENCODER_TYPE_VEC,
+ VC4_ENCODER_TYPE_DSI0,
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -177,8 +177,9 @@
+ # define PV_CONTROL_WAIT_HSTART BIT(12)
+ # define PV_CONTROL_PIXEL_REP_MASK VC4_MASK(5, 4)
+ # define PV_CONTROL_PIXEL_REP_SHIFT 4
+-# define PV_CONTROL_CLK_SELECT_DSI_VEC 0
++# define PV_CONTROL_CLK_SELECT_DSI 0
+ # define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI 1
++# define PV_CONTROL_CLK_SELECT_VEC 2
+ # define PV_CONTROL_CLK_SELECT_MASK VC4_MASK(3, 2)
+ # define PV_CONTROL_CLK_SELECT_SHIFT 2
+ # define PV_CONTROL_FIFO_CLR BIT(1)
diff --git a/target/linux/brcm2708/patches-4.9/0168-drm-Add-TV-connector-states-to-drm_connector_state.patch b/target/linux/brcm2708/patches-4.9/0168-drm-Add-TV-connector-states-to-drm_connector_state.patch
new file mode 100644
index 0000000000..39e6f11665
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0168-drm-Add-TV-connector-states-to-drm_connector_state.patch
@@ -0,0 +1,148 @@
+From 01ff94b770786a793c08fc7fcbecdd5f859a8958 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 2 Dec 2016 14:48:09 +0100
+Subject: [PATCH] drm: Add TV connector states to drm_connector_state
+
+Some generic TV connector properties are exposed in drm_mode_config, but
+they are currently handled independently in each DRM encoder driver.
+
+Extend the drm_connector_state to store TV related states, and modify the
+drm_atomic_connector_{set,get}_property() helpers to fill the connector
+state accordingly.
+
+Each driver is then responsible for checking and applying the new config
+in its ->atomic_mode_{check,set}() operations.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 299a16b163c95fbe1e3b1e142ba9c6ce9dab2c23)
+---
+ drivers/gpu/drm/drm_atomic.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
+ include/drm/drm_connector.h | 32 ++++++++++++++++++++++++++++
+ 2 files changed, 82 insertions(+)
+
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -989,12 +989,38 @@ int drm_atomic_connector_set_property(st
+ * now?) atomic writes to DPMS property:
+ */
+ return -EINVAL;
++ } else if (property == config->tv_select_subconnector_property) {
++ state->tv.subconnector = val;
++ } else if (property == config->tv_left_margin_property) {
++ state->tv.margins.left = val;
++ } else if (property == config->tv_right_margin_property) {
++ state->tv.margins.right = val;
++ } else if (property == config->tv_top_margin_property) {
++ state->tv.margins.top = val;
++ } else if (property == config->tv_bottom_margin_property) {
++ state->tv.margins.bottom = val;
++ } else if (property == config->tv_mode_property) {
++ state->tv.mode = val;
++ } else if (property == config->tv_brightness_property) {
++ state->tv.brightness = val;
++ } else if (property == config->tv_contrast_property) {
++ state->tv.contrast = val;
++ } else if (property == config->tv_flicker_reduction_property) {
++ state->tv.flicker_reduction = val;
++ } else if (property == config->tv_overscan_property) {
++ state->tv.overscan = val;
++ } else if (property == config->tv_saturation_property) {
++ state->tv.saturation = val;
++ } else if (property == config->tv_hue_property) {
++ state->tv.hue = val;
+ } else if (connector->funcs->atomic_set_property) {
+ return connector->funcs->atomic_set_property(connector,
+ state, property, val);
+ } else {
+ return -EINVAL;
+ }
++
++ return 0;
+ }
+ EXPORT_SYMBOL(drm_atomic_connector_set_property);
+
+@@ -1025,6 +1051,30 @@ drm_atomic_connector_get_property(struct
+ *val = (state->crtc) ? state->crtc->base.id : 0;
+ } else if (property == config->dpms_property) {
+ *val = connector->dpms;
++ } else if (property == config->tv_select_subconnector_property) {
++ *val = state->tv.subconnector;
++ } else if (property == config->tv_left_margin_property) {
++ *val = state->tv.margins.left;
++ } else if (property == config->tv_right_margin_property) {
++ *val = state->tv.margins.right;
++ } else if (property == config->tv_top_margin_property) {
++ *val = state->tv.margins.top;
++ } else if (property == config->tv_bottom_margin_property) {
++ *val = state->tv.margins.bottom;
++ } else if (property == config->tv_mode_property) {
++ *val = state->tv.mode;
++ } else if (property == config->tv_brightness_property) {
++ *val = state->tv.brightness;
++ } else if (property == config->tv_contrast_property) {
++ *val = state->tv.contrast;
++ } else if (property == config->tv_flicker_reduction_property) {
++ *val = state->tv.flicker_reduction;
++ } else if (property == config->tv_overscan_property) {
++ *val = state->tv.overscan;
++ } else if (property == config->tv_saturation_property) {
++ *val = state->tv.saturation;
++ } else if (property == config->tv_hue_property) {
++ *val = state->tv.hue;
+ } else if (connector->funcs->atomic_get_property) {
+ return connector->funcs->atomic_get_property(connector,
+ state, property, val);
+--- a/include/drm/drm_connector.h
++++ b/include/drm/drm_connector.h
+@@ -194,10 +194,40 @@ int drm_display_info_set_bus_formats(str
+ unsigned int num_formats);
+
+ /**
++ * struct drm_tv_connector_state - TV connector related states
++ * @subconnector: selected subconnector
++ * @margins: left/right/top/bottom margins
++ * @mode: TV mode
++ * @brightness: brightness in percent
++ * @contrast: contrast in percent
++ * @flicker_reduction: flicker reduction in percent
++ * @overscan: overscan in percent
++ * @saturation: saturation in percent
++ * @hue: hue in percent
++ */
++struct drm_tv_connector_state {
++ enum drm_mode_subconnector subconnector;
++ struct {
++ unsigned int left;
++ unsigned int right;
++ unsigned int top;
++ unsigned int bottom;
++ } margins;
++ unsigned int mode;
++ unsigned int brightness;
++ unsigned int contrast;
++ unsigned int flicker_reduction;
++ unsigned int overscan;
++ unsigned int saturation;
++ unsigned int hue;
++};
++
++/**
+ * struct drm_connector_state - mutable connector state
+ * @connector: backpointer to the connector
+ * @best_encoder: can be used by helpers and drivers to select the encoder
+ * @state: backpointer to global drm_atomic_state
++ * @tv: TV connector state
+ */
+ struct drm_connector_state {
+ struct drm_connector *connector;
+@@ -213,6 +243,8 @@ struct drm_connector_state {
+ struct drm_encoder *best_encoder;
+
+ struct drm_atomic_state *state;
++
++ struct drm_tv_connector_state tv;
+ };
+
+ /**
diff --git a/target/linux/brcm2708/patches-4.9/0169-drm-Turn-DRM_MODE_SUBCONNECTOR_xx-definitions-into-a.patch b/target/linux/brcm2708/patches-4.9/0169-drm-Turn-DRM_MODE_SUBCONNECTOR_xx-definitions-into-a.patch
new file mode 100644
index 0000000000..db82c0c5ac
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0169-drm-Turn-DRM_MODE_SUBCONNECTOR_xx-definitions-into-a.patch
@@ -0,0 +1,46 @@
+From 1c18e33ab3ff21703925a427e5f55075427a598c Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 2 Dec 2016 14:48:08 +0100
+Subject: [PATCH] drm: Turn DRM_MODE_SUBCONNECTOR_xx definitions into an enum
+
+List of values like the DRM_MODE_SUBCONNECTOR_xx ones are better
+represented with enums.
+
+Turn the DRM_MODE_SUBCONNECTOR_xx macros into an enum.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit dee7a4fee730ca8908f335b6b66174cba4598ecd)
+---
+ include/uapi/drm/drm_mode.h | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/include/uapi/drm/drm_mode.h
++++ b/include/uapi/drm/drm_mode.h
+@@ -220,14 +220,16 @@ struct drm_mode_get_encoder {
+
+ /* This is for connectors with multiple signal types. */
+ /* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
+-#define DRM_MODE_SUBCONNECTOR_Automatic 0
+-#define DRM_MODE_SUBCONNECTOR_Unknown 0
+-#define DRM_MODE_SUBCONNECTOR_DVID 3
+-#define DRM_MODE_SUBCONNECTOR_DVIA 4
+-#define DRM_MODE_SUBCONNECTOR_Composite 5
+-#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
+-#define DRM_MODE_SUBCONNECTOR_Component 8
+-#define DRM_MODE_SUBCONNECTOR_SCART 9
++enum drm_mode_subconnector {
++ DRM_MODE_SUBCONNECTOR_Automatic = 0,
++ DRM_MODE_SUBCONNECTOR_Unknown = 0,
++ DRM_MODE_SUBCONNECTOR_DVID = 3,
++ DRM_MODE_SUBCONNECTOR_DVIA = 4,
++ DRM_MODE_SUBCONNECTOR_Composite = 5,
++ DRM_MODE_SUBCONNECTOR_SVIDEO = 6,
++ DRM_MODE_SUBCONNECTOR_Component = 8,
++ DRM_MODE_SUBCONNECTOR_SCART = 9,
++};
+
+ #define DRM_MODE_CONNECTOR_Unknown 0
+ #define DRM_MODE_CONNECTOR_VGA 1
diff --git a/target/linux/brcm2708/patches-4.9/0170-drm-vc4-Add-support-for-the-VEC-Video-Encoder-IP.patch b/target/linux/brcm2708/patches-4.9/0170-drm-vc4-Add-support-for-the-VEC-Video-Encoder-IP.patch
new file mode 100644
index 0000000000..0b5a853856
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0170-drm-vc4-Add-support-for-the-VEC-Video-Encoder-IP.patch
@@ -0,0 +1,730 @@
+From d79cd118969fb3ad714feb834eefdddcc4348673 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 2 Dec 2016 14:48:10 +0100
+Subject: [PATCH] drm/vc4: Add support for the VEC (Video Encoder) IP
+
+The VEC IP is a TV DAC, providing support for PAL and NTSC standards.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit e4b81f8c74c82dbc0cb0e5ceb5ef9b713b325fc9)
+---
+ drivers/gpu/drm/vc4/Makefile | 1 +
+ drivers/gpu/drm/vc4/vc4_debugfs.c | 1 +
+ drivers/gpu/drm/vc4/vc4_drv.c | 1 +
+ drivers/gpu/drm/vc4/vc4_drv.h | 5 +
+ drivers/gpu/drm/vc4/vc4_vec.c | 657 ++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 665 insertions(+)
+ create mode 100644 drivers/gpu/drm/vc4/vc4_vec.c
+
+--- a/drivers/gpu/drm/vc4/Makefile
++++ b/drivers/gpu/drm/vc4/Makefile
+@@ -12,6 +12,7 @@ vc4-y := \
+ vc4_kms.o \
+ vc4_gem.o \
+ vc4_hdmi.o \
++ vc4_vec.o \
+ vc4_hvs.o \
+ vc4_irq.o \
+ vc4_plane.o \
+--- a/drivers/gpu/drm/vc4/vc4_debugfs.c
++++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
+@@ -19,6 +19,7 @@ static const struct drm_info_list vc4_de
+ {"bo_stats", vc4_bo_stats_debugfs, 0},
+ {"dpi_regs", vc4_dpi_debugfs_regs, 0},
+ {"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
++ {"vec_regs", vc4_vec_debugfs_regs, 0},
+ {"hvs_regs", vc4_hvs_debugfs_regs, 0},
+ {"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
+ {"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -294,6 +294,7 @@ static const struct component_master_ops
+
+ static struct platform_driver *const component_drivers[] = {
+ &vc4_hdmi_driver,
++ &vc4_vec_driver,
+ &vc4_dpi_driver,
+ &vc4_hvs_driver,
+ &vc4_crtc_driver,
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -20,6 +20,7 @@ struct vc4_dev {
+ struct vc4_crtc *crtc[3];
+ struct vc4_v3d *v3d;
+ struct vc4_dpi *dpi;
++ struct vc4_vec *vec;
+
+ struct drm_fbdev_cma *fbdev;
+
+@@ -494,6 +495,10 @@ int vc4_queue_seqno_cb(struct drm_device
+ extern struct platform_driver vc4_hdmi_driver;
+ int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
+
++/* vc4_hdmi.c */
++extern struct platform_driver vc4_vec_driver;
++int vc4_vec_debugfs_regs(struct seq_file *m, void *unused);
++
+ /* vc4_irq.c */
+ irqreturn_t vc4_irq(int irq, void *arg);
+ void vc4_irq_preinstall(struct drm_device *dev);
+--- /dev/null
++++ b/drivers/gpu/drm/vc4/vc4_vec.c
+@@ -0,0 +1,657 @@
++/*
++ * Copyright (C) 2016 Broadcom
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++/**
++ * DOC: VC4 SDTV module
++ */
++
++#include <drm/drm_atomic_helper.h>
++#include <drm/drm_crtc_helper.h>
++#include <drm/drm_edid.h>
++#include <drm/drm_panel.h>
++#include <linux/clk.h>
++#include <linux/component.h>
++#include <linux/of_graph.h>
++#include <linux/of_platform.h>
++#include <linux/pm_runtime.h>
++
++#include "vc4_drv.h"
++#include "vc4_regs.h"
++
++/* WSE Registers */
++#define VEC_WSE_RESET 0xc0
++
++#define VEC_WSE_CONTROL 0xc4
++#define VEC_WSE_WSS_ENABLE BIT(7)
++
++#define VEC_WSE_WSS_DATA 0xc8
++#define VEC_WSE_VPS_DATA1 0xcc
++#define VEC_WSE_VPS_CONTROL 0xd0
++
++/* VEC Registers */
++#define VEC_REVID 0x100
++
++#define VEC_CONFIG0 0x104
++#define VEC_CONFIG0_YDEL_MASK GENMASK(28, 26)
++#define VEC_CONFIG0_YDEL(x) ((x) << 26)
++#define VEC_CONFIG0_CDEL_MASK GENMASK(25, 24)
++#define VEC_CONFIG0_CDEL(x) ((x) << 24)
++#define VEC_CONFIG0_PBPR_FIL BIT(18)
++#define VEC_CONFIG0_CHROMA_GAIN_MASK GENMASK(17, 16)
++#define VEC_CONFIG0_CHROMA_GAIN_UNITY (0 << 16)
++#define VEC_CONFIG0_CHROMA_GAIN_1_32 (1 << 16)
++#define VEC_CONFIG0_CHROMA_GAIN_1_16 (2 << 16)
++#define VEC_CONFIG0_CHROMA_GAIN_1_8 (3 << 16)
++#define VEC_CONFIG0_CBURST_GAIN_MASK GENMASK(14, 13)
++#define VEC_CONFIG0_CBURST_GAIN_UNITY (0 << 13)
++#define VEC_CONFIG0_CBURST_GAIN_1_128 (1 << 13)
++#define VEC_CONFIG0_CBURST_GAIN_1_64 (2 << 13)
++#define VEC_CONFIG0_CBURST_GAIN_1_32 (3 << 13)
++#define VEC_CONFIG0_CHRBW1 BIT(11)
++#define VEC_CONFIG0_CHRBW0 BIT(10)
++#define VEC_CONFIG0_SYNCDIS BIT(9)
++#define VEC_CONFIG0_BURDIS BIT(8)
++#define VEC_CONFIG0_CHRDIS BIT(7)
++#define VEC_CONFIG0_PDEN BIT(6)
++#define VEC_CONFIG0_YCDELAY BIT(4)
++#define VEC_CONFIG0_RAMPEN BIT(2)
++#define VEC_CONFIG0_YCDIS BIT(2)
++#define VEC_CONFIG0_STD_MASK GENMASK(1, 0)
++#define VEC_CONFIG0_NTSC_STD 0
++#define VEC_CONFIG0_PAL_BDGHI_STD 1
++#define VEC_CONFIG0_PAL_N_STD 3
++
++#define VEC_SCHPH 0x108
++#define VEC_SOFT_RESET 0x10c
++#define VEC_CLMP0_START 0x144
++#define VEC_CLMP0_END 0x148
++#define VEC_FREQ3_2 0x180
++#define VEC_FREQ1_0 0x184
++
++#define VEC_CONFIG1 0x188
++#define VEC_CONFIG_VEC_RESYNC_OFF BIT(18)
++#define VEC_CONFIG_RGB219 BIT(17)
++#define VEC_CONFIG_CBAR_EN BIT(16)
++#define VEC_CONFIG_TC_OBB BIT(15)
++#define VEC_CONFIG1_OUTPUT_MODE_MASK GENMASK(12, 10)
++#define VEC_CONFIG1_C_Y_CVBS (0 << 10)
++#define VEC_CONFIG1_CVBS_Y_C (1 << 10)
++#define VEC_CONFIG1_PR_Y_PB (2 << 10)
++#define VEC_CONFIG1_RGB (4 << 10)
++#define VEC_CONFIG1_Y_C_CVBS (5 << 10)
++#define VEC_CONFIG1_C_CVBS_Y (6 << 10)
++#define VEC_CONFIG1_C_CVBS_CVBS (7 << 10)
++#define VEC_CONFIG1_DIS_CHR BIT(9)
++#define VEC_CONFIG1_DIS_LUMA BIT(8)
++#define VEC_CONFIG1_YCBCR_IN BIT(6)
++#define VEC_CONFIG1_DITHER_TYPE_LFSR 0
++#define VEC_CONFIG1_DITHER_TYPE_COUNTER BIT(5)
++#define VEC_CONFIG1_DITHER_EN BIT(4)
++#define VEC_CONFIG1_CYDELAY BIT(3)
++#define VEC_CONFIG1_LUMADIS BIT(2)
++#define VEC_CONFIG1_COMPDIS BIT(1)
++#define VEC_CONFIG1_CUSTOM_FREQ BIT(0)
++
++#define VEC_CONFIG2 0x18c
++#define VEC_CONFIG2_PROG_SCAN BIT(15)
++#define VEC_CONFIG2_SYNC_ADJ_MASK GENMASK(14, 12)
++#define VEC_CONFIG2_SYNC_ADJ(x) (((x) / 2) << 12)
++#define VEC_CONFIG2_PBPR_EN BIT(10)
++#define VEC_CONFIG2_UV_DIG_DIS BIT(6)
++#define VEC_CONFIG2_RGB_DIG_DIS BIT(5)
++#define VEC_CONFIG2_TMUX_MASK GENMASK(3, 2)
++#define VEC_CONFIG2_TMUX_DRIVE0 (0 << 2)
++#define VEC_CONFIG2_TMUX_RG_COMP (1 << 2)
++#define VEC_CONFIG2_TMUX_UV_YC (2 << 2)
++#define VEC_CONFIG2_TMUX_SYNC_YC (3 << 2)
++
++#define VEC_INTERRUPT_CONTROL 0x190
++#define VEC_INTERRUPT_STATUS 0x194
++#define VEC_FCW_SECAM_B 0x198
++#define VEC_SECAM_GAIN_VAL 0x19c
++
++#define VEC_CONFIG3 0x1a0
++#define VEC_CONFIG3_HORIZ_LEN_STD (0 << 0)
++#define VEC_CONFIG3_HORIZ_LEN_MPEG1_SIF (1 << 0)
++#define VEC_CONFIG3_SHAPE_NON_LINEAR BIT(1)
++
++#define VEC_STATUS0 0x200
++#define VEC_MASK0 0x204
++
++#define VEC_CFG 0x208
++#define VEC_CFG_SG_MODE_MASK GENMASK(6, 5)
++#define VEC_CFG_SG_MODE(x) ((x) << 5)
++#define VEC_CFG_SG_EN BIT(4)
++#define VEC_CFG_VEC_EN BIT(3)
++#define VEC_CFG_MB_EN BIT(2)
++#define VEC_CFG_ENABLE BIT(1)
++#define VEC_CFG_TB_EN BIT(0)
++
++#define VEC_DAC_TEST 0x20c
++
++#define VEC_DAC_CONFIG 0x210
++#define VEC_DAC_CONFIG_LDO_BIAS_CTRL(x) ((x) << 24)
++#define VEC_DAC_CONFIG_DRIVER_CTRL(x) ((x) << 16)
++#define VEC_DAC_CONFIG_DAC_CTRL(x) (x)
++
++#define VEC_DAC_MISC 0x214
++#define VEC_DAC_MISC_VCD_CTRL_MASK GENMASK(31, 16)
++#define VEC_DAC_MISC_VCD_CTRL(x) ((x) << 16)
++#define VEC_DAC_MISC_VID_ACT BIT(8)
++#define VEC_DAC_MISC_VCD_PWRDN BIT(6)
++#define VEC_DAC_MISC_BIAS_PWRDN BIT(5)
++#define VEC_DAC_MISC_DAC_PWRDN BIT(2)
++#define VEC_DAC_MISC_LDO_PWRDN BIT(1)
++#define VEC_DAC_MISC_DAC_RST_N BIT(0)
++
++
++/* General VEC hardware state. */
++struct vc4_vec {
++ struct platform_device *pdev;
++
++ struct drm_encoder *encoder;
++ struct drm_connector *connector;
++
++ void __iomem *regs;
++
++ struct clk *clock;
++
++ const struct vc4_vec_tv_mode *tv_mode;
++};
++
++#define VEC_READ(offset) readl(vec->regs + (offset))
++#define VEC_WRITE(offset, val) writel(val, vec->regs + (offset))
++
++/* VC4 VEC encoder KMS struct */
++struct vc4_vec_encoder {
++ struct vc4_encoder base;
++ struct vc4_vec *vec;
++};
++
++static inline struct vc4_vec_encoder *
++to_vc4_vec_encoder(struct drm_encoder *encoder)
++{
++ return container_of(encoder, struct vc4_vec_encoder, base.base);
++}
++
++/* VC4 VEC connector KMS struct */
++struct vc4_vec_connector {
++ struct drm_connector base;
++ struct vc4_vec *vec;
++
++ /* Since the connector is attached to just the one encoder,
++ * this is the reference to it so we can do the best_encoder()
++ * hook.
++ */
++ struct drm_encoder *encoder;
++};
++
++static inline struct vc4_vec_connector *
++to_vc4_vec_connector(struct drm_connector *connector)
++{
++ return container_of(connector, struct vc4_vec_connector, base);
++}
++
++enum vc4_vec_tv_mode_id {
++ VC4_VEC_TV_MODE_NTSC,
++ VC4_VEC_TV_MODE_NTSC_J,
++ VC4_VEC_TV_MODE_PAL,
++ VC4_VEC_TV_MODE_PAL_M,
++};
++
++struct vc4_vec_tv_mode {
++ const struct drm_display_mode *mode;
++ void (*mode_set)(struct vc4_vec *vec);
++};
++
++#define VEC_REG(reg) { reg, #reg }
++static const struct {
++ u32 reg;
++ const char *name;
++} vec_regs[] = {
++ VEC_REG(VEC_WSE_CONTROL),
++ VEC_REG(VEC_WSE_WSS_DATA),
++ VEC_REG(VEC_WSE_VPS_DATA1),
++ VEC_REG(VEC_WSE_VPS_CONTROL),
++ VEC_REG(VEC_REVID),
++ VEC_REG(VEC_CONFIG0),
++ VEC_REG(VEC_SCHPH),
++ VEC_REG(VEC_CLMP0_START),
++ VEC_REG(VEC_CLMP0_END),
++ VEC_REG(VEC_FREQ3_2),
++ VEC_REG(VEC_FREQ1_0),
++ VEC_REG(VEC_CONFIG1),
++ VEC_REG(VEC_CONFIG2),
++ VEC_REG(VEC_INTERRUPT_CONTROL),
++ VEC_REG(VEC_INTERRUPT_STATUS),
++ VEC_REG(VEC_FCW_SECAM_B),
++ VEC_REG(VEC_SECAM_GAIN_VAL),
++ VEC_REG(VEC_CONFIG3),
++ VEC_REG(VEC_STATUS0),
++ VEC_REG(VEC_MASK0),
++ VEC_REG(VEC_CFG),
++ VEC_REG(VEC_DAC_TEST),
++ VEC_REG(VEC_DAC_CONFIG),
++ VEC_REG(VEC_DAC_MISC),
++};
++
++#ifdef CONFIG_DEBUG_FS
++int vc4_vec_debugfs_regs(struct seq_file *m, void *unused)
++{
++ struct drm_info_node *node = (struct drm_info_node *)m->private;
++ struct drm_device *dev = node->minor->dev;
++ struct vc4_dev *vc4 = to_vc4_dev(dev);
++ struct vc4_vec *vec = vc4->vec;
++ int i;
++
++ if (!vec)
++ return 0;
++
++ for (i = 0; i < ARRAY_SIZE(vec_regs); i++) {
++ seq_printf(m, "%s (0x%04x): 0x%08x\n",
++ vec_regs[i].name, vec_regs[i].reg,
++ VEC_READ(vec_regs[i].reg));
++ }
++
++ return 0;
++}
++#endif
++
++static void vc4_vec_ntsc_mode_set(struct vc4_vec *vec)
++{
++ VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN);
++ VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS);
++}
++
++static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec)
++{
++ VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD);
++ VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS);
++}
++
++static const struct drm_display_mode ntsc_mode = {
++ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
++ 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
++ 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0,
++ DRM_MODE_FLAG_INTERLACE)
++};
++
++static void vc4_vec_pal_mode_set(struct vc4_vec *vec)
++{
++ VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD);
++ VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS);
++}
++
++static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec)
++{
++ VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD);
++ VEC_WRITE(VEC_CONFIG1,
++ VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ);
++ VEC_WRITE(VEC_FREQ3_2, 0x223b);
++ VEC_WRITE(VEC_FREQ1_0, 0x61d1);
++}
++
++static const struct drm_display_mode pal_mode = {
++ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
++ 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
++ 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0,
++ DRM_MODE_FLAG_INTERLACE)
++};
++
++static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
++ [VC4_VEC_TV_MODE_NTSC] = {
++ .mode = &ntsc_mode,
++ .mode_set = vc4_vec_ntsc_mode_set,
++ },
++ [VC4_VEC_TV_MODE_NTSC_J] = {
++ .mode = &ntsc_mode,
++ .mode_set = vc4_vec_ntsc_j_mode_set,
++ },
++ [VC4_VEC_TV_MODE_PAL] = {
++ .mode = &pal_mode,
++ .mode_set = vc4_vec_pal_mode_set,
++ },
++ [VC4_VEC_TV_MODE_PAL_M] = {
++ .mode = &pal_mode,
++ .mode_set = vc4_vec_pal_m_mode_set,
++ },
++};
++
++static enum drm_connector_status
++vc4_vec_connector_detect(struct drm_connector *connector, bool force)
++{
++ return connector_status_unknown;
++}
++
++static void vc4_vec_connector_destroy(struct drm_connector *connector)
++{
++ drm_connector_unregister(connector);
++ drm_connector_cleanup(connector);
++}
++
++static int vc4_vec_connector_get_modes(struct drm_connector *connector)
++{
++ struct drm_connector_state *state = connector->state;
++ struct drm_display_mode *mode;
++
++ mode = drm_mode_duplicate(connector->dev,
++ vc4_vec_tv_modes[state->tv.mode].mode);
++ if (!mode) {
++ DRM_ERROR("Failed to create a new display mode\n");
++ return -ENOMEM;
++ }
++
++ drm_mode_probed_add(connector, mode);
++
++ return 1;
++}
++
++static const struct drm_connector_funcs vc4_vec_connector_funcs = {
++ .dpms = drm_atomic_helper_connector_dpms,
++ .detect = vc4_vec_connector_detect,
++ .fill_modes = drm_helper_probe_single_connector_modes,
++ .set_property = drm_atomic_helper_connector_set_property,
++ .destroy = vc4_vec_connector_destroy,
++ .reset = drm_atomic_helper_connector_reset,
++ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
++ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
++};
++
++static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = {
++ .get_modes = vc4_vec_connector_get_modes,
++};
++
++static struct drm_connector *vc4_vec_connector_init(struct drm_device *dev,
++ struct vc4_vec *vec)
++{
++ struct drm_connector *connector = NULL;
++ struct vc4_vec_connector *vec_connector;
++
++ vec_connector = devm_kzalloc(dev->dev, sizeof(*vec_connector),
++ GFP_KERNEL);
++ if (!vec_connector)
++ return ERR_PTR(-ENOMEM);
++
++ connector = &vec_connector->base;
++ connector->interlace_allowed = true;
++
++ vec_connector->encoder = vec->encoder;
++ vec_connector->vec = vec;
++
++ drm_connector_init(dev, connector, &vc4_vec_connector_funcs,
++ DRM_MODE_CONNECTOR_Composite);
++ drm_connector_helper_add(connector, &vc4_vec_connector_helper_funcs);
++
++ drm_object_attach_property(&connector->base,
++ dev->mode_config.tv_mode_property,
++ VC4_VEC_TV_MODE_NTSC);
++ vec->tv_mode = &vc4_vec_tv_modes[VC4_VEC_TV_MODE_NTSC];
++
++ drm_mode_connector_attach_encoder(connector, vec->encoder);
++
++ return connector;
++}
++
++static const struct drm_encoder_funcs vc4_vec_encoder_funcs = {
++ .destroy = drm_encoder_cleanup,
++};
++
++static void vc4_vec_encoder_disable(struct drm_encoder *encoder)
++{
++ struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder);
++ struct vc4_vec *vec = vc4_vec_encoder->vec;
++ int ret;
++
++ VEC_WRITE(VEC_CFG, 0);
++ VEC_WRITE(VEC_DAC_MISC,
++ VEC_DAC_MISC_VCD_PWRDN |
++ VEC_DAC_MISC_BIAS_PWRDN |
++ VEC_DAC_MISC_DAC_PWRDN |
++ VEC_DAC_MISC_LDO_PWRDN);
++
++ clk_disable_unprepare(vec->clock);
++
++ ret = pm_runtime_put(&vec->pdev->dev);
++ if (ret < 0) {
++ DRM_ERROR("Failed to release power domain: %d\n", ret);
++ return;
++ }
++}
++
++static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
++{
++ struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder);
++ struct vc4_vec *vec = vc4_vec_encoder->vec;
++ int ret;
++
++ ret = pm_runtime_get_sync(&vec->pdev->dev);
++ if (ret < 0) {
++ DRM_ERROR("Failed to retain power domain: %d\n", ret);
++ return;
++ }
++
++ /*
++ * We need to set the clock rate each time we enable the encoder
++ * because there's a chance we share the same parent with the HDMI
++ * clock, and both drivers are requesting different rates.
++ * The good news is, these 2 encoders cannot be enabled at the same
++ * time, thus preventing incompatible rate requests.
++ */
++ ret = clk_set_rate(vec->clock, 108000000);
++ if (ret) {
++ DRM_ERROR("Failed to set clock rate: %d\n", ret);
++ return;
++ }
++
++ ret = clk_prepare_enable(vec->clock);
++ if (ret) {
++ DRM_ERROR("Failed to turn on core clock: %d\n", ret);
++ return;
++ }
++
++ /* Reset the different blocks */
++ VEC_WRITE(VEC_WSE_RESET, 1);
++ VEC_WRITE(VEC_SOFT_RESET, 1);
++
++ /* Disable the CGSM-A and WSE blocks */
++ VEC_WRITE(VEC_WSE_CONTROL, 0);
++
++ /* Write config common to all modes. */
++
++ /*
++ * Color subcarrier phase: phase = 360 * SCHPH / 256.
++ * 0x28 <=> 39.375 deg.
++ */
++ VEC_WRITE(VEC_SCHPH, 0x28);
++
++ /*
++ * Reset to default values.
++ */
++ VEC_WRITE(VEC_CLMP0_START, 0xac);
++ VEC_WRITE(VEC_CLMP0_END, 0xec);
++ VEC_WRITE(VEC_CONFIG2,
++ VEC_CONFIG2_UV_DIG_DIS | VEC_CONFIG2_RGB_DIG_DIS);
++ VEC_WRITE(VEC_CONFIG3, VEC_CONFIG3_HORIZ_LEN_STD);
++ VEC_WRITE(VEC_DAC_CONFIG,
++ VEC_DAC_CONFIG_DAC_CTRL(0xc) |
++ VEC_DAC_CONFIG_DRIVER_CTRL(0xc) |
++ VEC_DAC_CONFIG_LDO_BIAS_CTRL(0x46));
++
++ /* Mask all interrupts. */
++ VEC_WRITE(VEC_MASK0, 0);
++
++ vec->tv_mode->mode_set(vec);
++
++ VEC_WRITE(VEC_DAC_MISC,
++ VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N);
++ VEC_WRITE(VEC_CFG, VEC_CFG_VEC_EN);
++}
++
++
++static bool vc4_vec_encoder_mode_fixup(struct drm_encoder *encoder,
++ const struct drm_display_mode *mode,
++ struct drm_display_mode *adjusted_mode)
++{
++ return true;
++}
++
++static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder,
++ struct drm_crtc_state *crtc_state,
++ struct drm_connector_state *conn_state)
++{
++ struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder);
++ struct vc4_vec *vec = vc4_vec_encoder->vec;
++
++ vec->tv_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
++}
++
++static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
++ struct drm_crtc_state *crtc_state,
++ struct drm_connector_state *conn_state)
++{
++ const struct vc4_vec_tv_mode *vec_mode;
++
++ vec_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
++
++ if (conn_state->crtc &&
++ !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode))
++ return -EINVAL;
++
++ return 0;
++}
++
++static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
++ .disable = vc4_vec_encoder_disable,
++ .enable = vc4_vec_encoder_enable,
++ .mode_fixup = vc4_vec_encoder_mode_fixup,
++ .atomic_check = vc4_vec_encoder_atomic_check,
++ .atomic_mode_set = vc4_vec_encoder_atomic_mode_set,
++};
++
++static const struct of_device_id vc4_vec_dt_match[] = {
++ { .compatible = "brcm,bcm2835-vec", .data = NULL },
++ { /* sentinel */ },
++};
++
++static const char * const tv_mode_names[] = {
++ [VC4_VEC_TV_MODE_NTSC] = "NTSC",
++ [VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
++ [VC4_VEC_TV_MODE_PAL] = "PAL",
++ [VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
++};
++
++static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct drm_device *drm = dev_get_drvdata(master);
++ struct vc4_dev *vc4 = to_vc4_dev(drm);
++ struct vc4_vec *vec;
++ struct vc4_vec_encoder *vc4_vec_encoder;
++ int ret;
++
++ ret = drm_mode_create_tv_properties(drm, ARRAY_SIZE(tv_mode_names),
++ tv_mode_names);
++ if (ret)
++ return ret;
++
++ vec = devm_kzalloc(dev, sizeof(*vec), GFP_KERNEL);
++ if (!vec)
++ return -ENOMEM;
++
++ vc4_vec_encoder = devm_kzalloc(dev, sizeof(*vc4_vec_encoder),
++ GFP_KERNEL);
++ if (!vc4_vec_encoder)
++ return -ENOMEM;
++ vc4_vec_encoder->base.type = VC4_ENCODER_TYPE_VEC;
++ vc4_vec_encoder->vec = vec;
++ vec->encoder = &vc4_vec_encoder->base.base;
++
++ vec->pdev = pdev;
++ vec->regs = vc4_ioremap_regs(pdev, 0);
++ if (IS_ERR(vec->regs))
++ return PTR_ERR(vec->regs);
++
++ vec->clock = devm_clk_get(dev, NULL);
++ if (IS_ERR(vec->clock)) {
++ ret = PTR_ERR(vec->clock);
++ if (ret != -EPROBE_DEFER)
++ DRM_ERROR("Failed to get clock: %d\n", ret);
++ return ret;
++ }
++
++ pm_runtime_enable(dev);
++
++ drm_encoder_init(drm, vec->encoder, &vc4_vec_encoder_funcs,
++ DRM_MODE_ENCODER_TVDAC, NULL);
++ drm_encoder_helper_add(vec->encoder, &vc4_vec_encoder_helper_funcs);
++
++ vec->connector = vc4_vec_connector_init(drm, vec);
++ if (IS_ERR(vec->connector)) {
++ ret = PTR_ERR(vec->connector);
++ goto err_destroy_encoder;
++ }
++
++ dev_set_drvdata(dev, vec);
++
++ vc4->vec = vec;
++
++ return 0;
++
++err_destroy_encoder:
++ drm_encoder_cleanup(vec->encoder);
++ pm_runtime_disable(dev);
++
++ return ret;
++}
++
++static void vc4_vec_unbind(struct device *dev, struct device *master,
++ void *data)
++{
++ struct drm_device *drm = dev_get_drvdata(master);
++ struct vc4_dev *vc4 = to_vc4_dev(drm);
++ struct vc4_vec *vec = dev_get_drvdata(dev);
++
++ vc4_vec_connector_destroy(vec->connector);
++ drm_encoder_cleanup(vec->encoder);
++ pm_runtime_disable(dev);
++
++ vc4->vec = NULL;
++}
++
++static const struct component_ops vc4_vec_ops = {
++ .bind = vc4_vec_bind,
++ .unbind = vc4_vec_unbind,
++};
++
++static int vc4_vec_dev_probe(struct platform_device *pdev)
++{
++ return component_add(&pdev->dev, &vc4_vec_ops);
++}
++
++static int vc4_vec_dev_remove(struct platform_device *pdev)
++{
++ component_del(&pdev->dev, &vc4_vec_ops);
++ return 0;
++}
++
++struct platform_driver vc4_vec_driver = {
++ .probe = vc4_vec_dev_probe,
++ .remove = vc4_vec_dev_remove,
++ .driver = {
++ .name = "vc4_vec",
++ .of_match_table = vc4_vec_dt_match,
++ },
++};
diff --git a/target/linux/brcm2708/patches-4.9/0171-drm-vc4-Set-up-SCALER_DISPCTRL-at-boot.patch b/target/linux/brcm2708/patches-4.9/0171-drm-vc4-Set-up-SCALER_DISPCTRL-at-boot.patch
new file mode 100644
index 0000000000..1a425cac00
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0171-drm-vc4-Set-up-SCALER_DISPCTRL-at-boot.patch
@@ -0,0 +1,58 @@
+From e79b86a0c5ccd0e8c16e31b2d494d43e997253d1 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 15 Sep 2016 15:25:23 +0100
+Subject: [PATCH] drm/vc4: Set up SCALER_DISPCTRL at boot.
+
+We want the HVS on, obviously, and we also want DSP3 (PV1's source) to
+be muxed from HVS channel 2 like we expect in vc4_crtc.c. The
+firmware wasn't setting the DSP3 mux up when both the LCD and HDMI
+were disabled.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_hvs.c | 14 ++++++++++++++
+ drivers/gpu/drm/vc4/vc4_regs.h | 3 +++
+ 2 files changed, 17 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c
+@@ -170,6 +170,7 @@ static int vc4_hvs_bind(struct device *d
+ struct vc4_dev *vc4 = drm->dev_private;
+ struct vc4_hvs *hvs = NULL;
+ int ret;
++ u32 dispctrl;
+
+ hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
+ if (!hvs)
+@@ -211,6 +212,19 @@ static int vc4_hvs_bind(struct device *d
+ return ret;
+
+ vc4->hvs = hvs;
++
++ dispctrl = HVS_READ(SCALER_DISPCTRL);
++
++ dispctrl |= SCALER_DISPCTRL_ENABLE;
++
++ /* Set DSP3 (PV1) to use HVS channel 2, which would otherwise
++ * be unused.
++ */
++ dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK;
++ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
++
++ HVS_WRITE(SCALER_DISPCTRL, dispctrl);
++
+ return 0;
+ }
+
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -244,6 +244,9 @@
+ # define SCALER_DISPCTRL_ENABLE BIT(31)
+ # define SCALER_DISPCTRL_DSP2EISLUR BIT(15)
+ # define SCALER_DISPCTRL_DSP1EISLUR BIT(14)
++# define SCALER_DISPCTRL_DSP3_MUX_MASK VC4_MASK(19, 18)
++# define SCALER_DISPCTRL_DSP3_MUX_SHIFT 18
++
+ /* Enables Display 0 short line and underrun contribution to
+ * SCALER_DISPSTAT_IRQDISP0. Note that short frame contributions are
+ * always enabled.
diff --git a/target/linux/brcm2708/patches-4.9/0172-drm-vc4-Add-support-for-feeding-DSI-encoders-from-th.patch b/target/linux/brcm2708/patches-4.9/0172-drm-vc4-Add-support-for-feeding-DSI-encoders-from-th.patch
new file mode 100644
index 0000000000..15243a32b7
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0172-drm-vc4-Add-support-for-feeding-DSI-encoders-from-th.patch
@@ -0,0 +1,113 @@
+From 01ffdd37dcd3c9e526ac9135bfd289beb45f84a0 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 10 Feb 2016 16:17:29 -0800
+Subject: [PATCH] drm/vc4: Add support for feeding DSI encoders from the pixel
+ valve.
+
+We have to set a different pixel format, which tells the hardware to
+use the pix_width field that's fed in sideband from the DSI encoder to
+divide the "pixel" clock.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 33 +++++++++++++++++++--------------
+ drivers/gpu/drm/vc4/vc4_regs.h | 2 ++
+ 2 files changed, 21 insertions(+), 14 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -352,38 +352,40 @@ static u32 vc4_get_fifo_full_level(u32 f
+ }
+
+ /*
+- * Returns the clock select bit for the connector attached to the
+- * CRTC.
++ * Returns the encoder attached to the CRTC.
++ *
++ * VC4 can only scan out to one encoder at a time, while the DRM core
++ * allows drivers to push pixels to more than one encoder from the
++ * same CRTC.
+ */
+-static int vc4_get_clock_select(struct drm_crtc *crtc)
++static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc)
+ {
+ struct drm_connector *connector;
+
+ drm_for_each_connector(connector, crtc->dev) {
+ if (connector->state->crtc == crtc) {
+- struct drm_encoder *encoder = connector->encoder;
+- struct vc4_encoder *vc4_encoder =
+- to_vc4_encoder(encoder);
+-
+- return vc4_encoder->clock_select;
++ return connector->encoder;
+ }
+ }
+
+- return -1;
++ return NULL;
+ }
+
+ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+ {
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
++ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
++ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct drm_crtc_state *state = crtc->state;
+ struct drm_display_mode *mode = &state->adjusted_mode;
+ bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
+ u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
+- u32 format = PV_CONTROL_FORMAT_24;
++ bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
++ vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
++ u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
+ bool debug_dump_regs = false;
+- int clock_select = vc4_get_clock_select(crtc);
+
+ if (debug_dump_regs) {
+ DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
+@@ -439,17 +441,19 @@ static void vc4_crtc_mode_set_nofb(struc
+ */
+ CRTC_WRITE(PV_V_CONTROL,
+ PV_VCONTROL_CONTINUOUS |
++ (is_dsi ? PV_VCONTROL_DSI : 0) |
+ PV_VCONTROL_INTERLACE |
+ VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
+ PV_VCONTROL_ODD_DELAY));
+ CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+ } else {
+- CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
++ CRTC_WRITE(PV_V_CONTROL,
++ PV_VCONTROL_CONTINUOUS |
++ (is_dsi ? PV_VCONTROL_DSI : 0));
+ }
+
+ CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
+
+-
+ CRTC_WRITE(PV_CONTROL,
+ VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
+ VC4_SET_FIELD(vc4_get_fifo_full_level(format),
+@@ -458,7 +462,8 @@ static void vc4_crtc_mode_set_nofb(struc
+ PV_CONTROL_CLR_AT_START |
+ PV_CONTROL_TRIGGER_UNDERFLOW |
+ PV_CONTROL_WAIT_HSTART |
+- VC4_SET_FIELD(clock_select, PV_CONTROL_CLK_SELECT) |
++ VC4_SET_FIELD(vc4_encoder->clock_select,
++ PV_CONTROL_CLK_SELECT) |
+ PV_CONTROL_FIFO_CLR |
+ PV_CONTROL_EN);
+
+--- a/drivers/gpu/drm/vc4/vc4_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_regs.h
+@@ -190,6 +190,8 @@
+ # define PV_VCONTROL_ODD_DELAY_SHIFT 6
+ # define PV_VCONTROL_ODD_FIRST BIT(5)
+ # define PV_VCONTROL_INTERLACE BIT(4)
++# define PV_VCONTROL_DSI BIT(3)
++# define PV_VCONTROL_COMMAND BIT(2)
+ # define PV_VCONTROL_CONTINUOUS BIT(1)
+ # define PV_VCONTROL_VIDEN BIT(0)
+
diff --git a/target/linux/brcm2708/patches-4.9/0173-drm-vc4-Add-DSI-driver.patch b/target/linux/brcm2708/patches-4.9/0173-drm-vc4-Add-DSI-driver.patch
new file mode 100644
index 0000000000..97ae4a470a
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0173-drm-vc4-Add-DSI-driver.patch
@@ -0,0 +1,1817 @@
+From 38ea3f3665eaa9deedc3588196fe9ba9bb4032ec Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 10 Feb 2016 11:42:32 -0800
+Subject: [PATCH] drm/vc4: Add DSI driver
+
+The DSI0 and DSI1 blocks on the 2835 are related hardware blocks.
+Some registers move around, and the featureset is slightly different,
+as DSI1 (the 4-lane DSI) is a later version of the hardware block.
+This driver doesn't yet enable DSI0, since we don't have any hardware
+to test against, but it does put a lot of the register definitions and
+code in place.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/Kconfig | 2 +
+ drivers/gpu/drm/vc4/Makefile | 1 +
+ drivers/gpu/drm/vc4/vc4_debugfs.c | 1 +
+ drivers/gpu/drm/vc4/vc4_drv.c | 1 +
+ drivers/gpu/drm/vc4/vc4_drv.h | 5 +
+ drivers/gpu/drm/vc4/vc4_dsi.c | 1725 +++++++++++++++++++++++++++++++++++++
+ 6 files changed, 1735 insertions(+)
+ create mode 100644 drivers/gpu/drm/vc4/vc4_dsi.c
+
+--- a/drivers/gpu/drm/vc4/Kconfig
++++ b/drivers/gpu/drm/vc4/Kconfig
+@@ -2,10 +2,12 @@ config DRM_VC4
+ tristate "Broadcom VC4 Graphics"
+ depends on ARCH_BCM2835 || COMPILE_TEST
+ depends on DRM
++ depends on COMMON_CLK
+ select DRM_KMS_HELPER
+ select DRM_KMS_CMA_HELPER
+ select DRM_GEM_CMA_HELPER
+ select DRM_PANEL
++ select DRM_MIPI_DSI
+ help
+ Choose this option if you have a system that has a Broadcom
+ VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
+--- a/drivers/gpu/drm/vc4/Makefile
++++ b/drivers/gpu/drm/vc4/Makefile
+@@ -8,6 +8,7 @@ vc4-y := \
+ vc4_crtc.o \
+ vc4_drv.o \
+ vc4_dpi.o \
++ vc4_dsi.o \
+ vc4_firmware_kms.o \
+ vc4_kms.o \
+ vc4_gem.o \
+--- a/drivers/gpu/drm/vc4/vc4_debugfs.c
++++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
+@@ -18,6 +18,7 @@
+ static const struct drm_info_list vc4_debugfs_list[] = {
+ {"bo_stats", vc4_bo_stats_debugfs, 0},
+ {"dpi_regs", vc4_dpi_debugfs_regs, 0},
++ {"dsi1_regs", vc4_dsi_debugfs_regs, 0, (void *)(uintptr_t)1},
+ {"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
+ {"vec_regs", vc4_vec_debugfs_regs, 0},
+ {"hvs_regs", vc4_hvs_debugfs_regs, 0},
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -296,6 +296,7 @@ static struct platform_driver *const com
+ &vc4_hdmi_driver,
+ &vc4_vec_driver,
+ &vc4_dpi_driver,
++ &vc4_dsi_driver,
+ &vc4_hvs_driver,
+ &vc4_crtc_driver,
+ &vc4_firmware_kms_driver,
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -20,6 +20,7 @@ struct vc4_dev {
+ struct vc4_crtc *crtc[3];
+ struct vc4_v3d *v3d;
+ struct vc4_dpi *dpi;
++ struct vc4_dsi *dsi1;
+ struct vc4_vec *vec;
+
+ struct drm_fbdev_cma *fbdev;
+@@ -468,6 +469,10 @@ void __iomem *vc4_ioremap_regs(struct pl
+ extern struct platform_driver vc4_dpi_driver;
+ int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused);
+
++/* vc4_dsi.c */
++extern struct platform_driver vc4_dsi_driver;
++int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused);
++
+ /* vc4_firmware_kms.c */
+ extern struct platform_driver vc4_firmware_kms_driver;
+ void vc4_fkms_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
+--- /dev/null
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -0,0 +1,1725 @@
++/*
++ * Copyright (C) 2016 Broadcom
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++/**
++ * DOC: VC4 DSI0/DSI1 module
++ *
++ * BCM2835 contains two DSI modules, DSI0 and DSI1. DSI0 is a
++ * single-lane DSI controller, while DSI1 is a more modern 4-lane DSI
++ * controller.
++ *
++ * Most Raspberry Pi boards expose DSI1 as their "DISPLAY" connector,
++ * while the compute module brings both DSI0 and DSI1 out.
++ *
++ * This driver has been tested for DSI1 video-mode display only
++ * currently, with most of the information necessary for DSI0
++ * hopefully present.
++ */
++
++#include "drm_atomic_helper.h"
++#include "drm_crtc_helper.h"
++#include "drm_edid.h"
++#include "drm_mipi_dsi.h"
++#include "drm_panel.h"
++#include "linux/clk.h"
++#include "linux/clk-provider.h"
++#include "linux/completion.h"
++#include "linux/component.h"
++#include "linux/dmaengine.h"
++#include "linux/i2c.h"
++#include "linux/of_address.h"
++#include "linux/of_platform.h"
++#include "linux/pm_runtime.h"
++#include "vc4_drv.h"
++#include "vc4_regs.h"
++
++#define DSI_CMD_FIFO_DEPTH 16
++#define DSI_PIX_FIFO_DEPTH 256
++#define DSI_PIX_FIFO_WIDTH 4
++
++#define DSI0_CTRL 0x00
++
++/* Command packet control. */
++#define DSI0_TXPKT1C 0x04 /* AKA PKTC */
++#define DSI1_TXPKT1C 0x04
++# define DSI_TXPKT1C_TRIG_CMD_MASK VC4_MASK(31, 24)
++# define DSI_TXPKT1C_TRIG_CMD_SHIFT 24
++# define DSI_TXPKT1C_CMD_REPEAT_MASK VC4_MASK(23, 10)
++# define DSI_TXPKT1C_CMD_REPEAT_SHIFT 10
++
++# define DSI_TXPKT1C_DISPLAY_NO_MASK VC4_MASK(9, 8)
++# define DSI_TXPKT1C_DISPLAY_NO_SHIFT 8
++/* Short, trigger, BTA, or a long packet that fits all in CMDFIFO. */
++# define DSI_TXPKT1C_DISPLAY_NO_SHORT 0
++/* Primary display where cmdfifo provides part of the payload and
++ * pixelvalve the rest.
++ */
++# define DSI_TXPKT1C_DISPLAY_NO_PRIMARY 1
++/* Secondary display where cmdfifo provides part of the payload and
++ * pixfifo the rest.
++ */
++# define DSI_TXPKT1C_DISPLAY_NO_SECONDARY 2
++
++# define DSI_TXPKT1C_CMD_TX_TIME_MASK VC4_MASK(7, 6)
++# define DSI_TXPKT1C_CMD_TX_TIME_SHIFT 6
++
++# define DSI_TXPKT1C_CMD_CTRL_MASK VC4_MASK(5, 4)
++# define DSI_TXPKT1C_CMD_CTRL_SHIFT 4
++/* Command only. Uses TXPKT1H and DISPLAY_NO */
++# define DSI_TXPKT1C_CMD_CTRL_TX 0
++/* Command with BTA for either ack or read data. */
++# define DSI_TXPKT1C_CMD_CTRL_RX 1
++/* Trigger according to TRIG_CMD */
++# define DSI_TXPKT1C_CMD_CTRL_TRIG 2
++/* BTA alone for getting error status after a command, or a TE trigger
++ * without a previous command.
++ */
++# define DSI_TXPKT1C_CMD_CTRL_BTA 3
++
++# define DSI_TXPKT1C_CMD_MODE_LP BIT(3)
++# define DSI_TXPKT1C_CMD_TYPE_LONG BIT(2)
++# define DSI_TXPKT1C_CMD_TE_EN BIT(1)
++# define DSI_TXPKT1C_CMD_EN BIT(0)
++
++/* Command packet header. */
++#define DSI0_TXPKT1H 0x08 /* AKA PKTH */
++#define DSI1_TXPKT1H 0x08
++# define DSI_TXPKT1H_BC_CMDFIFO_MASK VC4_MASK(31, 24)
++# define DSI_TXPKT1H_BC_CMDFIFO_SHIFT 24
++# define DSI_TXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8)
++# define DSI_TXPKT1H_BC_PARAM_SHIFT 8
++# define DSI_TXPKT1H_BC_DT_MASK VC4_MASK(7, 0)
++# define DSI_TXPKT1H_BC_DT_SHIFT 0
++
++#define DSI0_RXPKT1H 0x0c /* AKA RX1_PKTH */
++#define DSI1_RXPKT1H 0x14
++# define DSI_RXPKT1H_CRC_ERR BIT(31)
++# define DSI_RXPKT1H_DET_ERR BIT(30)
++# define DSI_RXPKT1H_ECC_ERR BIT(29)
++# define DSI_RXPKT1H_COR_ERR BIT(28)
++# define DSI_RXPKT1H_INCOMP_PKT BIT(25)
++# define DSI_RXPKT1H_PKT_TYPE_LONG BIT(24)
++/* Byte count if DSI_RXPKT1H_PKT_TYPE_LONG */
++# define DSI_RXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8)
++# define DSI_RXPKT1H_BC_PARAM_SHIFT 8
++/* Short return bytes if !DSI_RXPKT1H_PKT_TYPE_LONG */
++# define DSI_RXPKT1H_SHORT_1_MASK VC4_MASK(23, 16)
++# define DSI_RXPKT1H_SHORT_1_SHIFT 16
++# define DSI_RXPKT1H_SHORT_0_MASK VC4_MASK(15, 8)
++# define DSI_RXPKT1H_SHORT_0_SHIFT 8
++# define DSI_RXPKT1H_DT_LP_CMD_MASK VC4_MASK(7, 0)
++# define DSI_RXPKT1H_DT_LP_CMD_SHIFT 0
++
++#define DSI0_RXPKT2H 0x10 /* AKA RX2_PKTH */
++#define DSI1_RXPKT2H 0x18
++# define DSI_RXPKT1H_DET_ERR BIT(30)
++# define DSI_RXPKT1H_ECC_ERR BIT(29)
++# define DSI_RXPKT1H_COR_ERR BIT(28)
++# define DSI_RXPKT1H_INCOMP_PKT BIT(25)
++# define DSI_RXPKT1H_BC_PARAM_MASK VC4_MASK(23, 8)
++# define DSI_RXPKT1H_BC_PARAM_SHIFT 8
++# define DSI_RXPKT1H_DT_MASK VC4_MASK(7, 0)
++# define DSI_RXPKT1H_DT_SHIFT 0
++
++#define DSI0_TXPKT_CMD_FIFO 0x14 /* AKA CMD_DATAF */
++#define DSI1_TXPKT_CMD_FIFO 0x1c
++
++#define DSI0_DISP0_CTRL 0x18
++# define DSI_DISP0_PIX_CLK_DIV_MASK VC4_MASK(21, 13)
++# define DSI_DISP0_PIX_CLK_DIV_SHIFT 13
++# define DSI_DISP0_LP_STOP_CTRL_MASK VC4_MASK(12, 11)
++# define DSI_DISP0_LP_STOP_CTRL_SHIFT 11
++# define DSI_DISP0_LP_STOP_DISABLE 0
++# define DSI_DISP0_LP_STOP_PERLINE 1
++# define DSI_DISP0_LP_STOP_PERFRAME 2
++
++/* Transmit RGB pixels and null packets only during HACTIVE, instead
++ * of going to LP-STOP.
++ */
++# define DSI_DISP_HACTIVE_NULL BIT(10)
++/* Transmit blanking packet only during vblank, instead of allowing LP-STOP. */
++# define DSI_DISP_VBLP_CTRL BIT(9)
++/* Transmit blanking packet only during HFP, instead of allowing LP-STOP. */
++# define DSI_DISP_HFP_CTRL BIT(8)
++/* Transmit blanking packet only during HBP, instead of allowing LP-STOP. */
++# define DSI_DISP_HBP_CTRL BIT(7)
++# define DSI_DISP0_CHANNEL_MASK VC4_MASK(6, 5)
++# define DSI_DISP0_CHANNEL_SHIFT 5
++/* Enables end events for HSYNC/VSYNC, not just start events. */
++# define DSI_DISP0_ST_END BIT(4)
++# define DSI_DISP0_PFORMAT_MASK VC4_MASK(3, 2)
++# define DSI_DISP0_PFORMAT_SHIFT 2
++# define DSI_PFORMAT_RGB565 0
++# define DSI_PFORMAT_RGB666_PACKED 1
++# define DSI_PFORMAT_RGB666 2
++# define DSI_PFORMAT_RGB888 3
++/* Default is VIDEO mode. */
++# define DSI_DISP0_COMMAND_MODE BIT(1)
++# define DSI_DISP0_ENABLE BIT(0)
++
++#define DSI0_DISP1_CTRL 0x1c
++#define DSI1_DISP1_CTRL 0x2c
++/* Format of the data written to TXPKT_PIX_FIFO. */
++# define DSI_DISP1_PFORMAT_MASK VC4_MASK(2, 1)
++# define DSI_DISP1_PFORMAT_SHIFT 1
++# define DSI_DISP1_PFORMAT_16BIT 0
++# define DSI_DISP1_PFORMAT_24BIT 1
++# define DSI_DISP1_PFORMAT_32BIT_LE 2
++# define DSI_DISP1_PFORMAT_32BIT_BE 3
++
++/* DISP1 is always command mode. */
++# define DSI_DISP1_ENABLE BIT(0)
++
++#define DSI0_TXPKT_PIX_FIFO 0x20 /* AKA PIX_FIFO */
++
++#define DSI0_INT_STAT 0x24
++#define DSI0_INT_EN 0x28
++# define DSI1_INT_PHY_D3_ULPS BIT(30)
++# define DSI1_INT_PHY_D3_STOP BIT(29)
++# define DSI1_INT_PHY_D2_ULPS BIT(28)
++# define DSI1_INT_PHY_D2_STOP BIT(27)
++# define DSI1_INT_PHY_D1_ULPS BIT(26)
++# define DSI1_INT_PHY_D1_STOP BIT(25)
++# define DSI1_INT_PHY_D0_ULPS BIT(24)
++# define DSI1_INT_PHY_D0_STOP BIT(23)
++# define DSI1_INT_FIFO_ERR BIT(22)
++# define DSI1_INT_PHY_DIR_RTF BIT(21)
++# define DSI1_INT_PHY_RXLPDT BIT(20)
++# define DSI1_INT_PHY_RXTRIG BIT(19)
++# define DSI1_INT_PHY_D0_LPDT BIT(18)
++# define DSI1_INT_PHY_DIR_FTR BIT(17)
++
++/* Signaled when the clock lane enters the given state. */
++# define DSI1_INT_PHY_CLOCK_ULPS BIT(16)
++# define DSI1_INT_PHY_CLOCK_HS BIT(15)
++# define DSI1_INT_PHY_CLOCK_STOP BIT(14)
++
++/* Signaled on timeouts */
++# define DSI1_INT_PR_TO BIT(13)
++# define DSI1_INT_TA_TO BIT(12)
++# define DSI1_INT_LPRX_TO BIT(11)
++# define DSI1_INT_HSTX_TO BIT(10)
++
++/* Contention on a line when trying to drive the line low */
++# define DSI1_INT_ERR_CONT_LP1 BIT(9)
++# define DSI1_INT_ERR_CONT_LP0 BIT(8)
++
++/* Control error: incorrect line state sequence on data lane 0. */
++# define DSI1_INT_ERR_CONTROL BIT(7)
++/* LPDT synchronization error (bits received not a multiple of 8. */
++
++# define DSI1_INT_ERR_SYNC_ESC BIT(6)
++/* Signaled after receiving an error packet from the display in
++ * response to a read.
++ */
++# define DSI1_INT_RXPKT2 BIT(5)
++/* Signaled after receiving a packet. The header and optional short
++ * response will be in RXPKT1H, and a long response will be in the
++ * RXPKT_FIFO.
++ */
++# define DSI1_INT_RXPKT1 BIT(4)
++# define DSI1_INT_TXPKT2_DONE BIT(3)
++# define DSI1_INT_TXPKT2_END BIT(2)
++/* Signaled after all repeats of TXPKT1 are transferred. */
++# define DSI1_INT_TXPKT1_DONE BIT(1)
++/* Signaled after each TXPKT1 repeat is scheduled. */
++# define DSI1_INT_TXPKT1_END BIT(0)
++
++#define DSI1_INTERRUPTS_ALWAYS_ENABLED (DSI1_INT_ERR_SYNC_ESC | \
++ DSI1_INT_ERR_CONTROL | \
++ DSI1_INT_ERR_CONT_LP0 | \
++ DSI1_INT_ERR_CONT_LP1 | \
++ DSI1_INT_HSTX_TO | \
++ DSI1_INT_LPRX_TO | \
++ DSI1_INT_TA_TO | \
++ DSI1_INT_PR_TO)
++
++#define DSI0_STAT 0x2c
++#define DSI0_HSTX_TO_CNT 0x30
++#define DSI0_LPRX_TO_CNT 0x34
++#define DSI0_TA_TO_CNT 0x38
++#define DSI0_PR_TO_CNT 0x3c
++#define DSI0_PHYC 0x40
++# define DSI1_PHYC_ESC_CLK_LPDT_MASK VC4_MASK(25, 20)
++# define DSI1_PHYC_ESC_CLK_LPDT_SHIFT 20
++# define DSI1_PHYC_HS_CLK_CONTINUOUS BIT(18)
++# define DSI0_PHYC_ESC_CLK_LPDT_MASK VC4_MASK(17, 12)
++# define DSI0_PHYC_ESC_CLK_LPDT_SHIFT 12
++# define DSI1_PHYC_CLANE_ULPS BIT(17)
++# define DSI1_PHYC_CLANE_ENABLE BIT(16)
++# define DSI_PHYC_DLANE3_ULPS BIT(13)
++# define DSI_PHYC_DLANE3_ENABLE BIT(12)
++# define DSI0_PHYC_HS_CLK_CONTINUOUS BIT(10)
++# define DSI0_PHYC_CLANE_ULPS BIT(9)
++# define DSI_PHYC_DLANE2_ULPS BIT(9)
++# define DSI0_PHYC_CLANE_ENABLE BIT(8)
++# define DSI_PHYC_DLANE2_ENABLE BIT(8)
++# define DSI_PHYC_DLANE1_ULPS BIT(5)
++# define DSI_PHYC_DLANE1_ENABLE BIT(4)
++# define DSI_PHYC_DLANE0_FORCE_STOP BIT(2)
++# define DSI_PHYC_DLANE0_ULPS BIT(1)
++# define DSI_PHYC_DLANE0_ENABLE BIT(0)
++
++#define DSI0_HS_CLT0 0x44
++#define DSI0_HS_CLT1 0x48
++#define DSI0_HS_CLT2 0x4c
++#define DSI0_HS_DLT3 0x50
++#define DSI0_HS_DLT4 0x54
++#define DSI0_HS_DLT5 0x58
++#define DSI0_HS_DLT6 0x5c
++#define DSI0_HS_DLT7 0x60
++
++#define DSI0_PHY_AFEC0 0x64
++# define DSI0_PHY_AFEC0_DDR2CLK_EN BIT(26)
++# define DSI0_PHY_AFEC0_DDRCLK_EN BIT(25)
++# define DSI0_PHY_AFEC0_LATCH_ULPS BIT(24)
++# define DSI1_PHY_AFEC0_IDR_DLANE3_MASK VC4_MASK(31, 29)
++# define DSI1_PHY_AFEC0_IDR_DLANE3_SHIFT 29
++# define DSI1_PHY_AFEC0_IDR_DLANE2_MASK VC4_MASK(28, 26)
++# define DSI1_PHY_AFEC0_IDR_DLANE2_SHIFT 26
++# define DSI1_PHY_AFEC0_IDR_DLANE1_MASK VC4_MASK(27, 23)
++# define DSI1_PHY_AFEC0_IDR_DLANE1_SHIFT 23
++# define DSI1_PHY_AFEC0_IDR_DLANE0_MASK VC4_MASK(22, 20)
++# define DSI1_PHY_AFEC0_IDR_DLANE0_SHIFT 20
++# define DSI1_PHY_AFEC0_IDR_CLANE_MASK VC4_MASK(19, 17)
++# define DSI1_PHY_AFEC0_IDR_CLANE_SHIFT 17
++# define DSI0_PHY_AFEC0_ACTRL_DLANE1_MASK VC4_MASK(23, 20)
++# define DSI0_PHY_AFEC0_ACTRL_DLANE1_SHIFT 20
++# define DSI0_PHY_AFEC0_ACTRL_DLANE0_MASK VC4_MASK(19, 16)
++# define DSI0_PHY_AFEC0_ACTRL_DLANE0_SHIFT 16
++# define DSI0_PHY_AFEC0_ACTRL_CLANE_MASK VC4_MASK(15, 12)
++# define DSI0_PHY_AFEC0_ACTRL_CLANE_SHIFT 12
++# define DSI1_PHY_AFEC0_DDR2CLK_EN BIT(16)
++# define DSI1_PHY_AFEC0_DDRCLK_EN BIT(15)
++# define DSI1_PHY_AFEC0_LATCH_ULPS BIT(14)
++# define DSI1_PHY_AFEC0_RESET BIT(13)
++# define DSI1_PHY_AFEC0_PD BIT(12)
++# define DSI0_PHY_AFEC0_RESET BIT(11)
++# define DSI1_PHY_AFEC0_PD_BG BIT(11)
++# define DSI0_PHY_AFEC0_PD BIT(10)
++# define DSI1_PHY_AFEC0_PD_DLANE3 BIT(10)
++# define DSI0_PHY_AFEC0_PD_BG BIT(9)
++# define DSI1_PHY_AFEC0_PD_DLANE2 BIT(9)
++# define DSI0_PHY_AFEC0_PD_DLANE1 BIT(8)
++# define DSI1_PHY_AFEC0_PD_DLANE1 BIT(8)
++# define DSI_PHY_AFEC0_PTATADJ_MASK VC4_MASK(7, 4)
++# define DSI_PHY_AFEC0_PTATADJ_SHIFT 4
++# define DSI_PHY_AFEC0_CTATADJ_MASK VC4_MASK(3, 0)
++# define DSI_PHY_AFEC0_CTATADJ_SHIFT 0
++
++#define DSI0_PHY_AFEC1 0x68
++# define DSI0_PHY_AFEC1_IDR_DLANE1_MASK VC4_MASK(10, 8)
++# define DSI0_PHY_AFEC1_IDR_DLANE1_SHIFT 8
++# define DSI0_PHY_AFEC1_IDR_DLANE0_MASK VC4_MASK(6, 4)
++# define DSI0_PHY_AFEC1_IDR_DLANE0_SHIFT 4
++# define DSI0_PHY_AFEC1_IDR_CLANE_MASK VC4_MASK(2, 0)
++# define DSI0_PHY_AFEC1_IDR_CLANE_SHIFT 0
++
++#define DSI0_TST_SEL 0x6c
++#define DSI0_TST_MON 0x70
++#define DSI0_ID 0x74
++# define DSI_ID_VALUE 0x00647369
++
++#define DSI1_CTRL 0x00
++# define DSI_CTRL_HS_CLKC_MASK VC4_MASK(15, 14)
++# define DSI_CTRL_HS_CLKC_SHIFT 14
++# define DSI_CTRL_HS_CLKC_BYTE 0
++# define DSI_CTRL_HS_CLKC_DDR2 1
++# define DSI_CTRL_HS_CLKC_DDR 2
++
++# define DSI_CTRL_RX_LPDT_EOT_DISABLE BIT(13)
++# define DSI_CTRL_LPDT_EOT_DISABLE BIT(12)
++# define DSI_CTRL_HSDT_EOT_DISABLE BIT(11)
++# define DSI_CTRL_SOFT_RESET_CFG BIT(10)
++# define DSI_CTRL_CAL_BYTE BIT(9)
++# define DSI_CTRL_INV_BYTE BIT(8)
++# define DSI_CTRL_CLR_LDF BIT(7)
++# define DSI0_CTRL_CLR_PBCF BIT(6)
++# define DSI1_CTRL_CLR_RXF BIT(6)
++# define DSI0_CTRL_CLR_CPBCF BIT(5)
++# define DSI1_CTRL_CLR_PDF BIT(5)
++# define DSI0_CTRL_CLR_PDF BIT(4)
++# define DSI1_CTRL_CLR_CDF BIT(4)
++# define DSI0_CTRL_CLR_CDF BIT(3)
++# define DSI0_CTRL_CTRL2 BIT(2)
++# define DSI1_CTRL_DISABLE_DISP_CRCC BIT(2)
++# define DSI0_CTRL_CTRL1 BIT(1)
++# define DSI1_CTRL_DISABLE_DISP_ECCC BIT(1)
++# define DSI0_CTRL_CTRL0 BIT(0)
++# define DSI1_CTRL_EN BIT(0)
++# define DSI0_CTRL_RESET_FIFOS (DSI_CTRL_CLR_LDF | \
++ DSI0_CTRL_CLR_PBCF | \
++ DSI0_CTRL_CLR_CPBCF | \
++ DSI0_CTRL_CLR_PDF | \
++ DSI0_CTRL_CLR_CDF)
++# define DSI1_CTRL_RESET_FIFOS (DSI_CTRL_CLR_LDF | \
++ DSI1_CTRL_CLR_RXF | \
++ DSI1_CTRL_CLR_PDF | \
++ DSI1_CTRL_CLR_CDF)
++
++#define DSI1_TXPKT2C 0x0c
++#define DSI1_TXPKT2H 0x10
++#define DSI1_TXPKT_PIX_FIFO 0x20
++#define DSI1_RXPKT_FIFO 0x24
++#define DSI1_DISP0_CTRL 0x28
++#define DSI1_INT_STAT 0x30
++#define DSI1_INT_EN 0x34
++/* State reporting bits. These mostly behave like INT_STAT, where
++ * writing a 1 clears the bit.
++ */
++#define DSI1_STAT 0x38
++# define DSI1_STAT_PHY_D3_ULPS BIT(31)
++# define DSI1_STAT_PHY_D3_STOP BIT(30)
++# define DSI1_STAT_PHY_D2_ULPS BIT(29)
++# define DSI1_STAT_PHY_D2_STOP BIT(28)
++# define DSI1_STAT_PHY_D1_ULPS BIT(27)
++# define DSI1_STAT_PHY_D1_STOP BIT(26)
++# define DSI1_STAT_PHY_D0_ULPS BIT(25)
++# define DSI1_STAT_PHY_D0_STOP BIT(24)
++# define DSI1_STAT_FIFO_ERR BIT(23)
++# define DSI1_STAT_PHY_RXLPDT BIT(22)
++# define DSI1_STAT_PHY_RXTRIG BIT(21)
++# define DSI1_STAT_PHY_D0_LPDT BIT(20)
++/* Set when in forward direction */
++# define DSI1_STAT_PHY_DIR BIT(19)
++# define DSI1_STAT_PHY_CLOCK_ULPS BIT(18)
++# define DSI1_STAT_PHY_CLOCK_HS BIT(17)
++# define DSI1_STAT_PHY_CLOCK_STOP BIT(16)
++# define DSI1_STAT_PR_TO BIT(15)
++# define DSI1_STAT_TA_TO BIT(14)
++# define DSI1_STAT_LPRX_TO BIT(13)
++# define DSI1_STAT_HSTX_TO BIT(12)
++# define DSI1_STAT_ERR_CONT_LP1 BIT(11)
++# define DSI1_STAT_ERR_CONT_LP0 BIT(10)
++# define DSI1_STAT_ERR_CONTROL BIT(9)
++# define DSI1_STAT_ERR_SYNC_ESC BIT(8)
++# define DSI1_STAT_RXPKT2 BIT(7)
++# define DSI1_STAT_RXPKT1 BIT(6)
++# define DSI1_STAT_TXPKT2_BUSY BIT(5)
++# define DSI1_STAT_TXPKT2_DONE BIT(4)
++# define DSI1_STAT_TXPKT2_END BIT(3)
++# define DSI1_STAT_TXPKT1_BUSY BIT(2)
++# define DSI1_STAT_TXPKT1_DONE BIT(1)
++# define DSI1_STAT_TXPKT1_END BIT(0)
++
++#define DSI1_HSTX_TO_CNT 0x3c
++#define DSI1_LPRX_TO_CNT 0x40
++#define DSI1_TA_TO_CNT 0x44
++#define DSI1_PR_TO_CNT 0x48
++#define DSI1_PHYC 0x4c
++
++#define DSI1_HS_CLT0 0x50
++# define DSI_HS_CLT0_CZERO_MASK VC4_MASK(26, 18)
++# define DSI_HS_CLT0_CZERO_SHIFT 18
++# define DSI_HS_CLT0_CPRE_MASK VC4_MASK(17, 9)
++# define DSI_HS_CLT0_CPRE_SHIFT 9
++# define DSI_HS_CLT0_CPREP_MASK VC4_MASK(8, 0)
++# define DSI_HS_CLT0_CPREP_SHIFT 0
++
++#define DSI1_HS_CLT1 0x54
++# define DSI_HS_CLT1_CTRAIL_MASK VC4_MASK(17, 9)
++# define DSI_HS_CLT1_CTRAIL_SHIFT 9
++# define DSI_HS_CLT1_CPOST_MASK VC4_MASK(8, 0)
++# define DSI_HS_CLT1_CPOST_SHIFT 0
++
++#define DSI1_HS_CLT2 0x58
++# define DSI_HS_CLT2_WUP_MASK VC4_MASK(23, 0)
++# define DSI_HS_CLT2_WUP_SHIFT 0
++
++#define DSI1_HS_DLT3 0x5c
++# define DSI_HS_DLT3_EXIT_MASK VC4_MASK(26, 18)
++# define DSI_HS_DLT3_EXIT_SHIFT 18
++# define DSI_HS_DLT3_ZERO_MASK VC4_MASK(17, 9)
++# define DSI_HS_DLT3_ZERO_SHIFT 9
++# define DSI_HS_DLT3_PRE_MASK VC4_MASK(8, 0)
++# define DSI_HS_DLT3_PRE_SHIFT 0
++
++#define DSI1_HS_DLT4 0x60
++# define DSI_HS_DLT4_ANLAT_MASK VC4_MASK(22, 18)
++# define DSI_HS_DLT4_ANLAT_SHIFT 18
++# define DSI_HS_DLT4_TRAIL_MASK VC4_MASK(17, 9)
++# define DSI_HS_DLT4_TRAIL_SHIFT 9
++# define DSI_HS_DLT4_LPX_MASK VC4_MASK(8, 0)
++# define DSI_HS_DLT4_LPX_SHIFT 0
++
++#define DSI1_HS_DLT5 0x64
++# define DSI_HS_DLT5_INIT_MASK VC4_MASK(23, 0)
++# define DSI_HS_DLT5_INIT_SHIFT 0
++
++#define DSI1_HS_DLT6 0x68
++# define DSI_HS_DLT6_TA_GET_MASK VC4_MASK(31, 24)
++# define DSI_HS_DLT6_TA_GET_SHIFT 24
++# define DSI_HS_DLT6_TA_SURE_MASK VC4_MASK(23, 16)
++# define DSI_HS_DLT6_TA_SURE_SHIFT 16
++# define DSI_HS_DLT6_TA_GO_MASK VC4_MASK(15, 8)
++# define DSI_HS_DLT6_TA_GO_SHIFT 8
++# define DSI_HS_DLT6_LP_LPX_MASK VC4_MASK(7, 0)
++# define DSI_HS_DLT6_LP_LPX_SHIFT 0
++
++#define DSI1_HS_DLT7 0x6c
++# define DSI_HS_DLT7_LP_WUP_MASK VC4_MASK(23, 0)
++# define DSI_HS_DLT7_LP_WUP_SHIFT 0
++
++#define DSI1_PHY_AFEC0 0x70
++
++#define DSI1_PHY_AFEC1 0x74
++# define DSI1_PHY_AFEC1_ACTRL_DLANE3_MASK VC4_MASK(19, 16)
++# define DSI1_PHY_AFEC1_ACTRL_DLANE3_SHIFT 16
++# define DSI1_PHY_AFEC1_ACTRL_DLANE2_MASK VC4_MASK(15, 12)
++# define DSI1_PHY_AFEC1_ACTRL_DLANE2_SHIFT 12
++# define DSI1_PHY_AFEC1_ACTRL_DLANE1_MASK VC4_MASK(11, 8)
++# define DSI1_PHY_AFEC1_ACTRL_DLANE1_SHIFT 8
++# define DSI1_PHY_AFEC1_ACTRL_DLANE0_MASK VC4_MASK(7, 4)
++# define DSI1_PHY_AFEC1_ACTRL_DLANE0_SHIFT 4
++# define DSI1_PHY_AFEC1_ACTRL_CLANE_MASK VC4_MASK(3, 0)
++# define DSI1_PHY_AFEC1_ACTRL_CLANE_SHIFT 0
++
++#define DSI1_TST_SEL 0x78
++#define DSI1_TST_MON 0x7c
++#define DSI1_PHY_TST1 0x80
++#define DSI1_PHY_TST2 0x84
++#define DSI1_PHY_FIFO_STAT 0x88
++/* Actually, all registers in the range that aren't otherwise claimed
++ * will return the ID.
++ */
++#define DSI1_ID 0x8c
++
++/* General DSI hardware state. */
++struct vc4_dsi {
++ struct platform_device *pdev;
++
++ struct mipi_dsi_host dsi_host;
++ struct drm_encoder *encoder;
++ struct drm_connector *connector;
++ struct drm_panel *panel;
++
++ void __iomem *regs;
++
++ struct dma_chan *reg_dma_chan;
++ dma_addr_t reg_dma_paddr;
++ u32 *reg_dma_mem;
++ dma_addr_t reg_paddr;
++
++ /* Whether we're on bcm2835's DSI0 or DSI1. */
++ int port;
++
++ /* DSI channel for the panel we're connected to. */
++ u32 channel;
++ u32 lanes;
++ enum mipi_dsi_pixel_format format;
++ u32 mode_flags;
++
++ /* Input clock from CPRMAN to the digital PHY, for the DSI
++ * escape clock.
++ */
++ struct clk *escape_clock;
++
++ /* Input clock to the analog PHY, used to generate the DSI bit
++ * clock.
++ */
++ struct clk *pll_phy_clock;
++
++ /* HS Clocks generated within the DSI analog PHY. */
++ struct clk_fixed_factor phy_clocks[3];
++
++ struct clk_onecell_data clk_onecell;
++
++ /* Pixel clock output to the pixelvalve, generated from the HS
++ * clock.
++ */
++ struct clk *pixel_clock;
++
++ struct completion xfer_completion;
++ int xfer_result;
++};
++
++#define host_to_dsi(host) container_of(host, struct vc4_dsi, dsi_host)
++
++static inline void
++dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val)
++{
++ struct dma_chan *chan = dsi->reg_dma_chan;
++ struct dma_async_tx_descriptor *tx;
++ dma_cookie_t cookie;
++ int ret;
++
++ /* DSI0 should be able to write normally. */
++ if (!chan) {
++ writel(val, dsi->regs + offset);
++ return;
++ }
++
++ *dsi->reg_dma_mem = val;
++
++ tx = chan->device->device_prep_dma_memcpy(chan,
++ dsi->reg_paddr + offset,
++ dsi->reg_dma_paddr,
++ 4, 0);
++ if (!tx) {
++ DRM_ERROR("Failed to set up DMA register write\n");
++ return;
++ }
++
++ cookie = tx->tx_submit(tx);
++ ret = dma_submit_error(cookie);
++ if (ret) {
++ DRM_ERROR("Failed to submit DMA: %d\n", ret);
++ return;
++ }
++ ret = dma_sync_wait(chan, cookie);
++ if (ret)
++ DRM_ERROR("Failed to wait for DMA: %d\n", ret);
++}
++
++#define DSI_READ(offset) readl(dsi->regs + (offset))
++#define DSI_WRITE(offset, val) dsi_dma_workaround_write(dsi, offset, val)
++#define DSI_PORT_READ(offset) \
++ DSI_READ(dsi->port ? DSI1_##offset : DSI0_##offset)
++#define DSI_PORT_WRITE(offset, val) \
++ DSI_WRITE(dsi->port ? DSI1_##offset : DSI0_##offset, val)
++#define DSI_PORT_BIT(bit) (dsi->port ? DSI1_##bit : DSI0_##bit)
++
++/* VC4 DSI encoder KMS struct */
++struct vc4_dsi_encoder {
++ struct vc4_encoder base;
++ struct vc4_dsi *dsi;
++};
++
++static inline struct vc4_dsi_encoder *
++to_vc4_dsi_encoder(struct drm_encoder *encoder)
++{
++ return container_of(encoder, struct vc4_dsi_encoder, base.base);
++}
++
++/* VC4 DSI connector KMS struct */
++struct vc4_dsi_connector {
++ struct drm_connector base;
++ struct vc4_dsi *dsi;
++};
++
++static inline struct vc4_dsi_connector *
++to_vc4_dsi_connector(struct drm_connector *connector)
++{
++ return container_of(connector, struct vc4_dsi_connector, base);
++}
++
++#define DSI_REG(reg) { reg, #reg }
++static const struct {
++ u32 reg;
++ const char *name;
++} dsi0_regs[] = {
++ DSI_REG(DSI0_CTRL),
++ DSI_REG(DSI0_STAT),
++ DSI_REG(DSI0_HSTX_TO_CNT),
++ DSI_REG(DSI0_LPRX_TO_CNT),
++ DSI_REG(DSI0_TA_TO_CNT),
++ DSI_REG(DSI0_PR_TO_CNT),
++ DSI_REG(DSI0_DISP0_CTRL),
++ DSI_REG(DSI0_DISP1_CTRL),
++ DSI_REG(DSI0_INT_STAT),
++ DSI_REG(DSI0_INT_EN),
++ DSI_REG(DSI0_PHYC),
++ DSI_REG(DSI0_HS_CLT0),
++ DSI_REG(DSI0_HS_CLT1),
++ DSI_REG(DSI0_HS_CLT2),
++ DSI_REG(DSI0_HS_DLT3),
++ DSI_REG(DSI0_HS_DLT4),
++ DSI_REG(DSI0_HS_DLT5),
++ DSI_REG(DSI0_HS_DLT6),
++ DSI_REG(DSI0_HS_DLT7),
++ DSI_REG(DSI0_PHY_AFEC0),
++ DSI_REG(DSI0_PHY_AFEC1),
++ DSI_REG(DSI0_ID),
++};
++
++static const struct {
++ u32 reg;
++ const char *name;
++} dsi1_regs[] = {
++ DSI_REG(DSI1_CTRL),
++ DSI_REG(DSI1_STAT),
++ DSI_REG(DSI1_HSTX_TO_CNT),
++ DSI_REG(DSI1_LPRX_TO_CNT),
++ DSI_REG(DSI1_TA_TO_CNT),
++ DSI_REG(DSI1_PR_TO_CNT),
++ DSI_REG(DSI1_DISP0_CTRL),
++ DSI_REG(DSI1_DISP1_CTRL),
++ DSI_REG(DSI1_INT_STAT),
++ DSI_REG(DSI1_INT_EN),
++ DSI_REG(DSI1_PHYC),
++ DSI_REG(DSI1_HS_CLT0),
++ DSI_REG(DSI1_HS_CLT1),
++ DSI_REG(DSI1_HS_CLT2),
++ DSI_REG(DSI1_HS_DLT3),
++ DSI_REG(DSI1_HS_DLT4),
++ DSI_REG(DSI1_HS_DLT5),
++ DSI_REG(DSI1_HS_DLT6),
++ DSI_REG(DSI1_HS_DLT7),
++ DSI_REG(DSI1_PHY_AFEC0),
++ DSI_REG(DSI1_PHY_AFEC1),
++ DSI_REG(DSI1_ID),
++};
++
++static void vc4_dsi_dump_regs(struct vc4_dsi *dsi)
++{
++ int i;
++
++ if (dsi->port == 0) {
++ for (i = 0; i < ARRAY_SIZE(dsi0_regs); i++) {
++ DRM_INFO("0x%04x (%s): 0x%08x\n",
++ dsi0_regs[i].reg, dsi0_regs[i].name,
++ DSI_READ(dsi0_regs[i].reg));
++ }
++ } else {
++ for (i = 0; i < ARRAY_SIZE(dsi1_regs); i++) {
++ DRM_INFO("0x%04x (%s): 0x%08x\n",
++ dsi1_regs[i].reg, dsi1_regs[i].name,
++ DSI_READ(dsi1_regs[i].reg));
++ }
++ }
++}
++
++#ifdef CONFIG_DEBUG_FS
++int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused)
++{
++ struct drm_info_node *node = (struct drm_info_node *)m->private;
++ struct drm_device *drm = node->minor->dev;
++ struct vc4_dev *vc4 = to_vc4_dev(drm);
++ int dsi_index = (uintptr_t)node->info_ent->data;
++ struct vc4_dsi *dsi = (dsi_index == 1 ? vc4->dsi1 : NULL);
++ int i;
++
++ if (!dsi)
++ return 0;
++
++ if (dsi->port == 0) {
++ for (i = 0; i < ARRAY_SIZE(dsi0_regs); i++) {
++ seq_printf(m, "0x%04x (%s): 0x%08x\n",
++ dsi0_regs[i].reg, dsi0_regs[i].name,
++ DSI_READ(dsi0_regs[i].reg));
++ }
++ } else {
++ for (i = 0; i < ARRAY_SIZE(dsi1_regs); i++) {
++ seq_printf(m, "0x%04x (%s): 0x%08x\n",
++ dsi1_regs[i].reg, dsi1_regs[i].name,
++ DSI_READ(dsi1_regs[i].reg));
++ }
++ }
++
++ return 0;
++}
++#endif
++
++static enum drm_connector_status
++vc4_dsi_connector_detect(struct drm_connector *connector, bool force)
++{
++ struct vc4_dsi_connector *vc4_connector =
++ to_vc4_dsi_connector(connector);
++ struct vc4_dsi *dsi = vc4_connector->dsi;
++
++ if (dsi->panel)
++ return connector_status_connected;
++ else
++ return connector_status_disconnected;
++}
++
++static void vc4_dsi_connector_destroy(struct drm_connector *connector)
++{
++ drm_connector_unregister(connector);
++ drm_connector_cleanup(connector);
++}
++
++static int vc4_dsi_connector_get_modes(struct drm_connector *connector)
++{
++ struct vc4_dsi_connector *vc4_connector =
++ to_vc4_dsi_connector(connector);
++ struct vc4_dsi *dsi = vc4_connector->dsi;
++
++ if (dsi->panel)
++ return drm_panel_get_modes(dsi->panel);
++
++ return 0;
++}
++
++static const struct drm_connector_funcs vc4_dsi_connector_funcs = {
++ .dpms = drm_atomic_helper_connector_dpms,
++ .detect = vc4_dsi_connector_detect,
++ .fill_modes = drm_helper_probe_single_connector_modes,
++ .destroy = vc4_dsi_connector_destroy,
++ .reset = drm_atomic_helper_connector_reset,
++ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
++ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
++};
++
++static const struct drm_connector_helper_funcs vc4_dsi_connector_helper_funcs = {
++ .get_modes = vc4_dsi_connector_get_modes,
++};
++
++static struct drm_connector *vc4_dsi_connector_init(struct drm_device *dev,
++ struct vc4_dsi *dsi)
++{
++ struct drm_connector *connector = NULL;
++ struct vc4_dsi_connector *dsi_connector;
++ int ret = 0;
++
++ dsi_connector = devm_kzalloc(dev->dev, sizeof(*dsi_connector),
++ GFP_KERNEL);
++ if (!dsi_connector) {
++ ret = -ENOMEM;
++ goto fail;
++ }
++ connector = &dsi_connector->base;
++
++ dsi_connector->dsi = dsi;
++
++ drm_connector_init(dev, connector, &vc4_dsi_connector_funcs,
++ DRM_MODE_CONNECTOR_DSI);
++ drm_connector_helper_add(connector, &vc4_dsi_connector_helper_funcs);
++
++ connector->polled = 0;
++ connector->interlace_allowed = 0;
++ connector->doublescan_allowed = 0;
++
++ drm_mode_connector_attach_encoder(connector, dsi->encoder);
++
++ return connector;
++
++fail:
++ if (connector)
++ vc4_dsi_connector_destroy(connector);
++
++ return ERR_PTR(ret);
++}
++
++static void vc4_dsi_encoder_destroy(struct drm_encoder *encoder)
++{
++ drm_encoder_cleanup(encoder);
++}
++
++static const struct drm_encoder_funcs vc4_dsi_encoder_funcs = {
++ .destroy = vc4_dsi_encoder_destroy,
++};
++
++static void vc4_dsi_latch_ulps(struct vc4_dsi *dsi, bool latch)
++{
++ u32 afec0 = DSI_PORT_READ(PHY_AFEC0);
++
++ if (latch)
++ afec0 |= DSI_PORT_BIT(PHY_AFEC0_LATCH_ULPS);
++ else
++ afec0 &= ~DSI_PORT_BIT(PHY_AFEC0_LATCH_ULPS);
++
++ DSI_PORT_WRITE(PHY_AFEC0, afec0);
++}
++
++/* Enters or exits Ultra Low Power State. */
++static void vc4_dsi_ulps(struct vc4_dsi *dsi, bool ulps)
++{
++ bool continuous = dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS;
++ u32 phyc_ulps = ((continuous ? DSI_PORT_BIT(PHYC_CLANE_ULPS) : 0) |
++ DSI_PHYC_DLANE0_ULPS |
++ (dsi->lanes > 1 ? DSI_PHYC_DLANE1_ULPS : 0) |
++ (dsi->lanes > 2 ? DSI_PHYC_DLANE2_ULPS : 0) |
++ (dsi->lanes > 3 ? DSI_PHYC_DLANE3_ULPS : 0));
++ u32 stat_ulps = ((continuous ? DSI1_STAT_PHY_CLOCK_ULPS : 0) |
++ DSI1_STAT_PHY_D0_ULPS |
++ (dsi->lanes > 1 ? DSI1_STAT_PHY_D1_ULPS : 0) |
++ (dsi->lanes > 2 ? DSI1_STAT_PHY_D2_ULPS : 0) |
++ (dsi->lanes > 3 ? DSI1_STAT_PHY_D3_ULPS : 0));
++ u32 stat_stop = ((continuous ? DSI1_STAT_PHY_CLOCK_STOP : 0) |
++ DSI1_STAT_PHY_D0_STOP |
++ (dsi->lanes > 1 ? DSI1_STAT_PHY_D1_STOP : 0) |
++ (dsi->lanes > 2 ? DSI1_STAT_PHY_D2_STOP : 0) |
++ (dsi->lanes > 3 ? DSI1_STAT_PHY_D3_STOP : 0));
++ int ret;
++
++ DSI_PORT_WRITE(STAT, stat_ulps);
++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) | phyc_ulps);
++ ret = wait_for((DSI_PORT_READ(STAT) & stat_ulps) == stat_ulps, 200);
++ if (ret) {
++ dev_warn(&dsi->pdev->dev,
++ "Timeout waiting for DSI ULPS entry: STAT 0x%08x",
++ DSI_PORT_READ(STAT));
++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps);
++ vc4_dsi_latch_ulps(dsi, false);
++ return;
++ }
++
++ /* The DSI module can't be disabled while the module is
++ * generating ULPS state. So, to be able to disable the
++ * module, we have the AFE latch the ULPS state and continue
++ * on to having the module enter STOP.
++ */
++ vc4_dsi_latch_ulps(dsi, ulps);
++
++ DSI_PORT_WRITE(STAT, stat_stop);
++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps);
++ ret = wait_for((DSI_PORT_READ(STAT) & stat_stop) == stat_stop, 200);
++ if (ret) {
++ dev_warn(&dsi->pdev->dev,
++ "Timeout waiting for DSI STOP entry: STAT 0x%08x",
++ DSI_PORT_READ(STAT));
++ DSI_PORT_WRITE(PHYC, DSI_PORT_READ(PHYC) & ~phyc_ulps);
++ return;
++ }
++}
++
++static u32
++dsi_hs_timing(u32 ui_ns, u32 ns, u32 ui)
++{
++ /* The HS timings have to be rounded up to a multiple of 8
++ * because we're using the byte clock.
++ */
++ return roundup(ui + DIV_ROUND_UP(ns, ui_ns), 8);
++}
++
++/* ESC always runs at 100Mhz. */
++#define ESC_TIME_NS 10
++
++static u32
++dsi_esc_timing(u32 ns)
++{
++ return DIV_ROUND_UP(ns, ESC_TIME_NS);
++}
++
++static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
++{
++ struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
++ struct vc4_dsi *dsi = vc4_encoder->dsi;
++ struct device *dev = &dsi->pdev->dev;
++
++ drm_panel_disable(dsi->panel);
++
++ vc4_dsi_ulps(dsi, true);
++
++ drm_panel_unprepare(dsi->panel);
++
++ clk_disable_unprepare(dsi->pll_phy_clock);
++ clk_disable_unprepare(dsi->escape_clock);
++ clk_disable_unprepare(dsi->pixel_clock);
++
++ pm_runtime_put(dev);
++}
++
++static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
++{
++ struct drm_display_mode *mode = &encoder->crtc->mode;
++ struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
++ struct vc4_dsi *dsi = vc4_encoder->dsi;
++ struct device *dev = &dsi->pdev->dev;
++ u32 format = 0, divider = 0;
++ bool debug_dump_regs = false;
++ unsigned long hs_clock;
++ u32 ui_ns;
++ /* Minimum LP state duration in escape clock cycles. */
++ u32 lpx = dsi_esc_timing(60);
++ unsigned long pixel_clock_hz = mode->clock * 1000;
++ unsigned long dsip_clock;
++ unsigned long phy_clock;
++ int ret;
++
++ ret = pm_runtime_get_sync(dev);
++ if (ret) {
++ DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->port);
++ return;
++ }
++
++ ret = drm_panel_prepare(dsi->panel);
++ if (ret) {
++ DRM_ERROR("Panel failed to prepare\n");
++ return;
++ }
++
++ if (debug_dump_regs) {
++ DRM_INFO("DSI regs before:\n");
++ vc4_dsi_dump_regs(dsi);
++ }
++
++ switch (dsi->format) {
++ case MIPI_DSI_FMT_RGB888:
++ format = DSI_PFORMAT_RGB888;
++ divider = 24 / dsi->lanes;
++ break;
++ case MIPI_DSI_FMT_RGB666:
++ format = DSI_PFORMAT_RGB666;
++ divider = 24 / dsi->lanes;
++ break;
++ case MIPI_DSI_FMT_RGB666_PACKED:
++ format = DSI_PFORMAT_RGB666_PACKED;
++ divider = 18 / dsi->lanes;
++ break;
++ case MIPI_DSI_FMT_RGB565:
++ format = DSI_PFORMAT_RGB565;
++ divider = 16 / dsi->lanes;
++ break;
++ }
++
++ phy_clock = pixel_clock_hz * divider;
++ ret = clk_set_rate(dsi->pll_phy_clock, phy_clock);
++ if (ret) {
++ dev_err(&dsi->pdev->dev,
++ "Failed to set phy clock to %ld: %d\n", phy_clock, ret);
++ }
++
++ /* Reset the DSI and all its fifos. */
++ DSI_PORT_WRITE(CTRL,
++ DSI_CTRL_SOFT_RESET_CFG |
++ DSI_PORT_BIT(CTRL_RESET_FIFOS));
++
++ DSI_PORT_WRITE(CTRL,
++ DSI_CTRL_HSDT_EOT_DISABLE |
++ DSI_CTRL_RX_LPDT_EOT_DISABLE);
++
++ /* Clear all stat bits so we see what has happened during enable. */
++ DSI_PORT_WRITE(STAT, DSI_PORT_READ(STAT));
++
++ /* Set AFE CTR00/CTR1 to release powerdown of analog. */
++ if (dsi->port == 0) {
++ u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) |
++ VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ));
++
++ if (dsi->lanes < 2)
++ afec0 |= DSI0_PHY_AFEC0_PD_DLANE1;
++
++ if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO))
++ afec0 |= DSI0_PHY_AFEC0_RESET;
++
++ DSI_PORT_WRITE(PHY_AFEC0, afec0);
++
++ DSI_PORT_WRITE(PHY_AFEC1,
++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE1) |
++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE0) |
++ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_CLANE));
++ } else {
++ u32 afec0 = (VC4_SET_FIELD(7, DSI_PHY_AFEC0_PTATADJ) |
++ VC4_SET_FIELD(7, DSI_PHY_AFEC0_CTATADJ) |
++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_CLANE) |
++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE0) |
++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE1) |
++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE2) |
++ VC4_SET_FIELD(6, DSI1_PHY_AFEC0_IDR_DLANE3));
++
++ if (dsi->lanes < 4)
++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE3;
++ if (dsi->lanes < 3)
++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE2;
++ if (dsi->lanes < 2)
++ afec0 |= DSI1_PHY_AFEC0_PD_DLANE1;
++
++ afec0 |= DSI1_PHY_AFEC0_RESET;
++
++ DSI_PORT_WRITE(PHY_AFEC0, afec0);
++
++ DSI_PORT_WRITE(PHY_AFEC1, 0);
++
++ /* AFEC reset hold time */
++ mdelay(1);
++ }
++
++ ret = clk_prepare_enable(dsi->escape_clock);
++ if (ret) {
++ DRM_ERROR("Failed to turn on DSI escape clock: %d\n", ret);
++ return;
++ }
++
++ ret = clk_prepare_enable(dsi->pll_phy_clock);
++ if (ret) {
++ DRM_ERROR("Failed to turn on DSI PLL: %d\n", ret);
++ return;
++ }
++
++ hs_clock = clk_get_rate(dsi->pll_phy_clock);
++
++ /* Yes, we set the DSI0P/DSI1P pixel clock to the byte rate,
++ * not the pixel clock rate. DSIxP take from the APHY's byte,
++ * DDR2, or DDR4 clock (we use byte) and feed into the PV at
++ * that rate. Separately, a value derived from PIX_CLK_DIV
++ * and HS_CLKC is fed into the PV to divide down to the actual
++ * pixel clock for pushing pixels into DSI.
++ */
++ dsip_clock = phy_clock / 8;
++ ret = clk_set_rate(dsi->pixel_clock, dsip_clock);
++ if (ret) {
++ dev_err(dev, "Failed to set pixel clock to %ldHz: %d\n",
++ dsip_clock, ret);
++ }
++
++ ret = clk_prepare_enable(dsi->pixel_clock);
++ if (ret) {
++ DRM_ERROR("Failed to turn on DSI pixel clock: %d\n", ret);
++ return;
++ }
++
++ /* How many ns one DSI unit interval is. Note that the clock
++ * is DDR, so there's an extra divide by 2.
++ */
++ ui_ns = DIV_ROUND_UP(500000000, hs_clock);
++
++ DSI_PORT_WRITE(HS_CLT0,
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 262, 0),
++ DSI_HS_CLT0_CZERO) |
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 0, 8),
++ DSI_HS_CLT0_CPRE) |
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 38, 0),
++ DSI_HS_CLT0_CPREP));
++
++ DSI_PORT_WRITE(HS_CLT1,
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 60, 0),
++ DSI_HS_CLT1_CTRAIL) |
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 60, 52),
++ DSI_HS_CLT1_CPOST));
++
++ DSI_PORT_WRITE(HS_CLT2,
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000000, 0),
++ DSI_HS_CLT2_WUP));
++
++ DSI_PORT_WRITE(HS_DLT3,
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 100, 0),
++ DSI_HS_DLT3_EXIT) |
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 105, 6),
++ DSI_HS_DLT3_ZERO) |
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, 40, 4),
++ DSI_HS_DLT3_PRE));
++
++ DSI_PORT_WRITE(HS_DLT4,
++ VC4_SET_FIELD(dsi_hs_timing(ui_ns, lpx * ESC_TIME_NS, 0),
++ DSI_HS_DLT4_LPX) |
++ VC4_SET_FIELD(max(dsi_hs_timing(ui_ns, 0, 8),
++ dsi_hs_timing(ui_ns, 60, 4)),
++ DSI_HS_DLT4_TRAIL) |
++ VC4_SET_FIELD(0, DSI_HS_DLT4_ANLAT));
++
++ DSI_PORT_WRITE(HS_DLT5, VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000, 5000),
++ DSI_HS_DLT5_INIT));
++
++ DSI_PORT_WRITE(HS_DLT6,
++ VC4_SET_FIELD(lpx * 5, DSI_HS_DLT6_TA_GET) |
++ VC4_SET_FIELD(lpx, DSI_HS_DLT6_TA_SURE) |
++ VC4_SET_FIELD(lpx * 4, DSI_HS_DLT6_TA_GO) |
++ VC4_SET_FIELD(lpx, DSI_HS_DLT6_LP_LPX));
++
++ DSI_PORT_WRITE(HS_DLT7,
++ VC4_SET_FIELD(dsi_esc_timing(1000000),
++ DSI_HS_DLT7_LP_WUP));
++
++ DSI_PORT_WRITE(PHYC,
++ DSI_PHYC_DLANE0_ENABLE |
++ (dsi->lanes >= 2 ? DSI_PHYC_DLANE1_ENABLE : 0) |
++ (dsi->lanes >= 3 ? DSI_PHYC_DLANE2_ENABLE : 0) |
++ (dsi->lanes >= 4 ? DSI_PHYC_DLANE3_ENABLE : 0) |
++ DSI_PORT_BIT(PHYC_CLANE_ENABLE) |
++ ((dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ?
++ 0 : DSI_PORT_BIT(PHYC_HS_CLK_CONTINUOUS)) |
++ (dsi->port == 0 ?
++ VC4_SET_FIELD(lpx - 1, DSI0_PHYC_ESC_CLK_LPDT) :
++ VC4_SET_FIELD(lpx - 1, DSI1_PHYC_ESC_CLK_LPDT)));
++
++ DSI_PORT_WRITE(CTRL,
++ DSI_PORT_READ(CTRL) |
++ DSI_CTRL_CAL_BYTE);
++
++ /* HS timeout in HS clock cycles: disabled. */
++ DSI_PORT_WRITE(HSTX_TO_CNT, 0);
++ /* LP receive timeout in HS clocks. */
++ DSI_PORT_WRITE(LPRX_TO_CNT, 0xffffff);
++ /* Bus turnaround timeout */
++ DSI_PORT_WRITE(TA_TO_CNT, 100000);
++ /* Display reset sequence timeout */
++ DSI_PORT_WRITE(PR_TO_CNT, 100000);
++
++ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
++ DSI_PORT_WRITE(DISP0_CTRL,
++ VC4_SET_FIELD(divider, DSI_DISP0_PIX_CLK_DIV) |
++ VC4_SET_FIELD(format, DSI_DISP0_PFORMAT) |
++ VC4_SET_FIELD(DSI_DISP0_LP_STOP_PERFRAME,
++ DSI_DISP0_LP_STOP_CTRL) |
++ DSI_DISP0_ST_END |
++ DSI_DISP0_ENABLE);
++ } else {
++ DSI_PORT_WRITE(DISP0_CTRL,
++ DSI_DISP0_COMMAND_MODE |
++ DSI_DISP0_ENABLE);
++ }
++
++ /* Set up DISP1 for transferring long command payloads through
++ * the pixfifo.
++ */
++ DSI_PORT_WRITE(DISP1_CTRL,
++ VC4_SET_FIELD(DSI_DISP1_PFORMAT_32BIT_LE,
++ DSI_DISP1_PFORMAT) |
++ DSI_DISP1_ENABLE);
++
++ /* Ungate the block. */
++ if (dsi->port == 0)
++ DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI0_CTRL_CTRL0);
++ else
++ DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN);
++
++ /* Bring AFE out of reset. */
++ if (dsi->port == 0) {
++ } else {
++ DSI_PORT_WRITE(PHY_AFEC0,
++ DSI_PORT_READ(PHY_AFEC0) &
++ ~DSI1_PHY_AFEC0_RESET);
++ }
++
++ vc4_dsi_ulps(dsi, false);
++
++ if (debug_dump_regs) {
++ DRM_INFO("DSI regs after:\n");
++ vc4_dsi_dump_regs(dsi);
++ }
++
++ ret = drm_panel_enable(dsi->panel);
++ if (ret) {
++ DRM_ERROR("Panel failed to enable\n");
++ drm_panel_unprepare(dsi->panel);
++ return;
++ }
++}
++
++static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
++ const struct mipi_dsi_msg *msg)
++{
++ struct vc4_dsi *dsi = host_to_dsi(host);
++ struct mipi_dsi_packet packet;
++ u32 pkth = 0, pktc = 0;
++ int i, ret;
++ bool is_long = mipi_dsi_packet_format_is_long(msg->type);
++ u32 cmd_fifo_len = 0, pix_fifo_len = 0;
++
++ mipi_dsi_create_packet(&packet, msg);
++
++ pkth |= VC4_SET_FIELD(packet.header[0], DSI_TXPKT1H_BC_DT);
++ pkth |= VC4_SET_FIELD(packet.header[1] |
++ (packet.header[2] << 8),
++ DSI_TXPKT1H_BC_PARAM);
++ if (is_long) {
++ /* Divide data across the various FIFOs we have available.
++ * The command FIFO takes byte-oriented data, but is of
++ * limited size. The pixel FIFO (never actually used for
++ * pixel data in reality) is word oriented, and substantially
++ * larger. So, we use the pixel FIFO for most of the data,
++ * sending the residual bytes in the command FIFO at the start.
++ *
++ * With this arrangement, the command FIFO will never get full.
++ */
++ if (packet.payload_length <= 16) {
++ cmd_fifo_len = packet.payload_length;
++ pix_fifo_len = 0;
++ } else {
++ cmd_fifo_len = (packet.payload_length %
++ DSI_PIX_FIFO_WIDTH);
++ pix_fifo_len = ((packet.payload_length - cmd_fifo_len) /
++ DSI_PIX_FIFO_WIDTH);
++ }
++
++ WARN_ON_ONCE(pix_fifo_len >= DSI_PIX_FIFO_DEPTH);
++
++ pkth |= VC4_SET_FIELD(cmd_fifo_len, DSI_TXPKT1H_BC_CMDFIFO);
++ }
++
++ if (msg->rx_len) {
++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_CMD_CTRL_RX,
++ DSI_TXPKT1C_CMD_CTRL);
++ } else {
++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_CMD_CTRL_TX,
++ DSI_TXPKT1C_CMD_CTRL);
++ }
++
++ for (i = 0; i < cmd_fifo_len; i++)
++ DSI_PORT_WRITE(TXPKT_CMD_FIFO, packet.payload[i]);
++ for (i = 0; i < pix_fifo_len; i++) {
++ const u8 *pix = packet.payload + cmd_fifo_len + i * 4;
++
++ DSI_PORT_WRITE(TXPKT_PIX_FIFO,
++ pix[0] |
++ pix[1] << 8 |
++ pix[2] << 16 |
++ pix[3] << 24);
++ }
++
++ if (msg->flags & MIPI_DSI_MSG_USE_LPM)
++ pktc |= DSI_TXPKT1C_CMD_MODE_LP;
++ if (is_long)
++ pktc |= DSI_TXPKT1C_CMD_TYPE_LONG;
++
++ /* Send one copy of the packet. Larger repeats are used for pixel
++ * data in command mode.
++ */
++ pktc |= VC4_SET_FIELD(1, DSI_TXPKT1C_CMD_REPEAT);
++
++ pktc |= DSI_TXPKT1C_CMD_EN;
++ if (pix_fifo_len) {
++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_DISPLAY_NO_SECONDARY,
++ DSI_TXPKT1C_DISPLAY_NO);
++ } else {
++ pktc |= VC4_SET_FIELD(DSI_TXPKT1C_DISPLAY_NO_SHORT,
++ DSI_TXPKT1C_DISPLAY_NO);
++ }
++
++ /* Enable the appropriate interrupt for the transfer completion. */
++ dsi->xfer_result = 0;
++ reinit_completion(&dsi->xfer_completion);
++ DSI_PORT_WRITE(INT_STAT, DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF);
++ if (msg->rx_len) {
++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
++ DSI1_INT_PHY_DIR_RTF));
++ } else {
++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
++ DSI1_INT_TXPKT1_DONE));
++ }
++
++ /* Send the packet. */
++ DSI_PORT_WRITE(TXPKT1H, pkth);
++ DSI_PORT_WRITE(TXPKT1C, pktc);
++
++ if (!wait_for_completion_timeout(&dsi->xfer_completion,
++ msecs_to_jiffies(1000))) {
++ dev_err(&dsi->pdev->dev, "transfer interrupt wait timeout");
++ dev_err(&dsi->pdev->dev, "instat: 0x%08x\n",
++ DSI_PORT_READ(INT_STAT));
++ ret = -ETIMEDOUT;
++ } else {
++ ret = dsi->xfer_result;
++ }
++
++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED);
++
++ if (ret)
++ goto reset_fifo_and_return;
++
++ if (ret == 0 && msg->rx_len) {
++ u32 rxpkt1h = DSI_PORT_READ(RXPKT1H);
++ u8 *msg_rx = msg->rx_buf;
++
++ if (rxpkt1h & DSI_RXPKT1H_PKT_TYPE_LONG) {
++ u32 rxlen = VC4_GET_FIELD(rxpkt1h,
++ DSI_RXPKT1H_BC_PARAM);
++
++ if (rxlen != msg->rx_len) {
++ DRM_ERROR("DSI returned %db, expecting %db\n",
++ rxlen, (int)msg->rx_len);
++ ret = -ENXIO;
++ goto reset_fifo_and_return;
++ }
++
++ for (i = 0; i < msg->rx_len; i++)
++ msg_rx[i] = DSI_READ(DSI1_RXPKT_FIFO);
++ } else {
++ /* FINISHME: Handle AWER */
++
++ msg_rx[0] = VC4_GET_FIELD(rxpkt1h,
++ DSI_RXPKT1H_SHORT_0);
++ if (msg->rx_len > 1) {
++ msg_rx[1] = VC4_GET_FIELD(rxpkt1h,
++ DSI_RXPKT1H_SHORT_1);
++ }
++ }
++ }
++
++ return ret;
++
++reset_fifo_and_return:
++ DRM_ERROR("DSI transfer failed, resetting: %d\n", ret);
++
++ DSI_PORT_WRITE(TXPKT1C, DSI_PORT_READ(TXPKT1C) & ~DSI_TXPKT1C_CMD_EN);
++ udelay(1);
++ DSI_PORT_WRITE(CTRL,
++ DSI_PORT_READ(CTRL) |
++ DSI_PORT_BIT(CTRL_RESET_FIFOS));
++
++ DSI_PORT_WRITE(TXPKT1C, 0);
++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED);
++ return ret;
++}
++
++static int vc4_dsi_host_attach(struct mipi_dsi_host *host,
++ struct mipi_dsi_device *device)
++{
++ struct vc4_dsi *dsi = host_to_dsi(host);
++ int ret = 0;
++
++ dsi->lanes = device->lanes;
++ dsi->channel = device->channel;
++ dsi->format = device->format;
++ dsi->mode_flags = device->mode_flags;
++
++ if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) {
++ dev_err(&dsi->pdev->dev,
++ "Only VIDEO mode panels supported currently.\n");
++ return 0;
++ }
++
++ dsi->panel = of_drm_find_panel(device->dev.of_node);
++ if (!dsi->panel)
++ return 0;
++
++ ret = drm_panel_attach(dsi->panel, dsi->connector);
++ if (ret != 0)
++ return ret;
++
++ drm_helper_hpd_irq_event(dsi->connector->dev);
++
++ return 0;
++}
++
++static int vc4_dsi_host_detach(struct mipi_dsi_host *host,
++ struct mipi_dsi_device *device)
++{
++ struct vc4_dsi *dsi = host_to_dsi(host);
++
++ if (dsi->panel) {
++ int ret = drm_panel_detach(dsi->panel);
++
++ if (ret)
++ return ret;
++
++ dsi->panel = NULL;
++
++ drm_helper_hpd_irq_event(dsi->connector->dev);
++ }
++
++ return 0;
++}
++
++static const struct mipi_dsi_host_ops vc4_dsi_host_ops = {
++ .attach = vc4_dsi_host_attach,
++ .detach = vc4_dsi_host_detach,
++ .transfer = vc4_dsi_host_transfer,
++};
++
++static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = {
++ .disable = vc4_dsi_encoder_disable,
++ .enable = vc4_dsi_encoder_enable,
++};
++
++static const struct of_device_id vc4_dsi_dt_match[] = {
++ { .compatible = "brcm,bcm2835-dsi1", (void *)(uintptr_t)1 },
++ {}
++};
++
++static void dsi_handle_error(struct vc4_dsi *dsi,
++ irqreturn_t *ret, u32 stat, u32 bit,
++ const char *type)
++{
++ if (!(stat & bit))
++ return;
++
++ DRM_ERROR("DSI%d: %s error\n", dsi->port, type);
++ *ret = IRQ_HANDLED;
++}
++
++static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)
++{
++ struct vc4_dsi *dsi = data;
++ u32 stat = DSI_PORT_READ(INT_STAT);
++ irqreturn_t ret = IRQ_NONE;
++
++ DSI_PORT_WRITE(INT_STAT, stat);
++
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_ERR_SYNC_ESC, "LPDT sync");
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_ERR_CONTROL, "data lane 0 sequence");
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_ERR_CONT_LP0, "LP0 contention");
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_ERR_CONT_LP1, "LP1 contention");
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_HSTX_TO, "HSTX timeout");
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_LPRX_TO, "LPRX timeout");
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_TA_TO, "turnaround timeout");
++ dsi_handle_error(dsi, &ret, stat,
++ DSI1_INT_PR_TO, "peripheral reset timeout");
++
++ if (stat & (DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF)) {
++ complete(&dsi->xfer_completion);
++ ret = IRQ_HANDLED;
++ } else if (stat & DSI1_INT_HSTX_TO) {
++ complete(&dsi->xfer_completion);
++ dsi->xfer_result = -ETIMEDOUT;
++ ret = IRQ_HANDLED;
++ }
++
++ return ret;
++}
++
++/**
++ * Exposes clocks generated by the analog PHY that are consumed by
++ * CPRMAN (clk-bcm2835.c).
++ */
++static int
++vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi)
++{
++ struct device *dev = &dsi->pdev->dev;
++ const char *parent_name = __clk_get_name(dsi->pll_phy_clock);
++ static const struct {
++ const char *dsi0_name, *dsi1_name;
++ int div;
++ } phy_clocks[] = {
++ { "dsi0_byte", "dsi1_byte", 8 },
++ { "dsi0_ddr2", "dsi1_ddr2", 4 },
++ { "dsi0_ddr", "dsi1_ddr", 2 },
++ };
++ int i;
++
++ dsi->clk_onecell.clk_num = ARRAY_SIZE(phy_clocks);
++ dsi->clk_onecell.clks = devm_kcalloc(dev,
++ dsi->clk_onecell.clk_num,
++ sizeof(*dsi->clk_onecell.clks),
++ GFP_KERNEL);
++ if (!dsi->clk_onecell.clks)
++ return -ENOMEM;
++
++ for (i = 0; i < ARRAY_SIZE(phy_clocks); i++) {
++ struct clk_fixed_factor *fix = &dsi->phy_clocks[i];
++ struct clk_init_data init;
++ struct clk *clk;
++
++ /* We just use core fixed factor clock ops for the PHY
++ * clocks. The clocks are actually gated by the
++ * PHY_AFEC0_DDRCLK_EN bits, which we should be
++ * setting if we use the DDR/DDR2 clocks. However,
++ * vc4_dsi_encoder_enable() is setting up both AFEC0,
++ * setting both our parent DSI PLL's rate and this
++ * clock's rate, so it knows if DDR/DDR2 are going to
++ * be used and could enable the gates itself.
++ */
++ fix->mult = 1;
++ fix->div = phy_clocks[i].div;
++ fix->hw.init = &init;
++
++ memset(&init, 0, sizeof(init));
++ init.parent_names = &parent_name;
++ init.num_parents = 1;
++ if (dsi->port == 1)
++ init.name = phy_clocks[i].dsi1_name;
++ else
++ init.name = phy_clocks[i].dsi0_name;
++ init.ops = &clk_fixed_factor_ops;
++ init.flags = CLK_IS_BASIC;
++
++ clk = devm_clk_register(dev, &fix->hw);
++ if (IS_ERR(clk))
++ return PTR_ERR(clk);
++
++ dsi->clk_onecell.clks[i] = clk;
++ }
++
++ return of_clk_add_provider(dev->of_node,
++ of_clk_src_onecell_get,
++ &dsi->clk_onecell);
++}
++
++static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct drm_device *drm = dev_get_drvdata(master);
++ struct vc4_dev *vc4 = to_vc4_dev(drm);
++ struct vc4_dsi *dsi;
++ struct vc4_dsi_encoder *vc4_dsi_encoder;
++ const struct of_device_id *match;
++ dma_cap_mask_t dma_mask;
++ int ret;
++
++ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
++ if (!dsi)
++ return -ENOMEM;
++
++ match = of_match_device(vc4_dsi_dt_match, dev);
++ if (!match)
++ return -ENODEV;
++
++ dsi->port = (uintptr_t)match->data;
++
++ vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder),
++ GFP_KERNEL);
++ if (!vc4_dsi_encoder)
++ return -ENOMEM;
++ vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1;
++ vc4_dsi_encoder->dsi = dsi;
++ dsi->encoder = &vc4_dsi_encoder->base.base;
++
++ dsi->pdev = pdev;
++ dsi->regs = vc4_ioremap_regs(pdev, 0);
++ if (IS_ERR(dsi->regs))
++ return PTR_ERR(dsi->regs);
++
++ if (DSI_PORT_READ(ID) != DSI_ID_VALUE) {
++ dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n",
++ DSI_PORT_READ(ID), DSI_ID_VALUE);
++ return -ENODEV;
++ }
++
++ /* DSI1 has a broken AXI slave that doesn't respond to writes
++ * from the ARM. It does handle writes from the DMA engine,
++ * so set up a channel for talking to it.
++ */
++ if (dsi->port == 1) {
++ dsi->reg_dma_mem = dma_alloc_coherent(dev, 4,
++ &dsi->reg_dma_paddr,
++ GFP_KERNEL);
++ if (!dsi->reg_dma_mem) {
++ DRM_ERROR("Failed to get DMA memory\n");
++ return -ENOMEM;
++ }
++
++ dma_cap_zero(dma_mask);
++ dma_cap_set(DMA_MEMCPY, dma_mask);
++ dsi->reg_dma_chan = dma_request_chan_by_mask(&dma_mask);
++ if (IS_ERR(dsi->reg_dma_chan)) {
++ ret = PTR_ERR(dsi->reg_dma_chan);
++ if (ret != -EPROBE_DEFER)
++ DRM_ERROR("Failed to get DMA channel: %d\n",
++ ret);
++ return ret;
++ }
++
++ /* Get the physical address of the device's registers. The
++ * struct resource for the regs gives us the bus address
++ * instead.
++ */
++ dsi->reg_paddr = be32_to_cpup(of_get_address(dev->of_node,
++ 0, NULL, NULL));
++ }
++
++ init_completion(&dsi->xfer_completion);
++ /* At startup enable error-reporting interrupts and nothing else. */
++ DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED);
++ /* Clear any existing interrupt state. */
++ DSI_PORT_WRITE(INT_STAT, DSI_PORT_READ(INT_STAT));
++
++ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
++ vc4_dsi_irq_handler, 0, "vc4 dsi", dsi);
++ if (ret) {
++ if (ret != -EPROBE_DEFER)
++ dev_err(dev, "Failed to get interrupt: %d\n", ret);
++ return ret;
++ }
++
++ dsi->escape_clock = devm_clk_get(dev, "escape");
++ if (IS_ERR(dsi->escape_clock)) {
++ ret = PTR_ERR(dsi->escape_clock);
++ if (ret != -EPROBE_DEFER)
++ dev_err(dev, "Failed to get escape clock: %d\n", ret);
++ return ret;
++ }
++
++ dsi->pll_phy_clock = devm_clk_get(dev, "phy");
++ if (IS_ERR(dsi->pll_phy_clock)) {
++ ret = PTR_ERR(dsi->pll_phy_clock);
++ if (ret != -EPROBE_DEFER)
++ dev_err(dev, "Failed to get phy clock: %d\n", ret);
++ return ret;
++ }
++
++ dsi->pixel_clock = devm_clk_get(dev, "pixel");
++ if (IS_ERR(dsi->pixel_clock)) {
++ ret = PTR_ERR(dsi->pixel_clock);
++ if (ret != -EPROBE_DEFER)
++ dev_err(dev, "Failed to get pixel clock: %d\n", ret);
++ return ret;
++ }
++
++ /* The esc clock rate is supposed to always be 100Mhz. */
++ ret = clk_set_rate(dsi->escape_clock, 100 * 1000000);
++ if (ret) {
++ dev_err(dev, "Failed to set esc clock: %d\n", ret);
++ return ret;
++ }
++
++ ret = vc4_dsi_init_phy_clocks(dsi);
++ if (ret)
++ return ret;
++
++ if (dsi->port == 1)
++ vc4->dsi1 = dsi;
++
++ drm_encoder_init(drm, dsi->encoder, &vc4_dsi_encoder_funcs,
++ DRM_MODE_ENCODER_DSI, NULL);
++ drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs);
++
++ dsi->connector = vc4_dsi_connector_init(drm, dsi);
++ if (IS_ERR(dsi->connector)) {
++ ret = PTR_ERR(dsi->connector);
++ goto err_destroy_encoder;
++ }
++
++ dsi->dsi_host.ops = &vc4_dsi_host_ops;
++ dsi->dsi_host.dev = dev;
++
++ mipi_dsi_host_register(&dsi->dsi_host);
++
++ dev_set_drvdata(dev, dsi);
++
++ pm_runtime_enable(dev);
++
++ return 0;
++
++err_destroy_encoder:
++ vc4_dsi_encoder_destroy(dsi->encoder);
++
++ return ret;
++}
++
++static void vc4_dsi_unbind(struct device *dev, struct device *master,
++ void *data)
++{
++ struct drm_device *drm = dev_get_drvdata(master);
++ struct vc4_dev *vc4 = to_vc4_dev(drm);
++ struct vc4_dsi *dsi = dev_get_drvdata(dev);
++
++ pm_runtime_disable(dev);
++
++ vc4_dsi_connector_destroy(dsi->connector);
++ vc4_dsi_encoder_destroy(dsi->encoder);
++
++ mipi_dsi_host_unregister(&dsi->dsi_host);
++
++ clk_disable_unprepare(dsi->pll_phy_clock);
++ clk_disable_unprepare(dsi->escape_clock);
++
++ if (dsi->port == 1)
++ vc4->dsi1 = NULL;
++}
++
++static const struct component_ops vc4_dsi_ops = {
++ .bind = vc4_dsi_bind,
++ .unbind = vc4_dsi_unbind,
++};
++
++static int vc4_dsi_dev_probe(struct platform_device *pdev)
++{
++ return component_add(&pdev->dev, &vc4_dsi_ops);
++}
++
++static int vc4_dsi_dev_remove(struct platform_device *pdev)
++{
++ component_del(&pdev->dev, &vc4_dsi_ops);
++ return 0;
++}
++
++struct platform_driver vc4_dsi_driver = {
++ .probe = vc4_dsi_dev_probe,
++ .remove = vc4_dsi_dev_remove,
++ .driver = {
++ .name = "vc4_dsi",
++ .of_match_table = vc4_dsi_dt_match,
++ },
++};
diff --git a/target/linux/brcm2708/patches-4.9/0174-ARM-dts-bcm283x-Add-VEC-node-in-bcm283x.dtsi.patch b/target/linux/brcm2708/patches-4.9/0174-ARM-dts-bcm283x-Add-VEC-node-in-bcm283x.dtsi.patch
new file mode 100644
index 0000000000..a2671f2439
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0174-ARM-dts-bcm283x-Add-VEC-node-in-bcm283x.dtsi.patch
@@ -0,0 +1,31 @@
+From 9389f17c3c92c3ec54e0d689ad46b95b90a8039a Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 2 Dec 2016 14:48:12 +0100
+Subject: [PATCH] ARM: dts: bcm283x: Add VEC node in bcm283x.dtsi
+
+Add the VEC (Video EnCoder) node definition in bcm283x.dtsi.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit b899c45208d6f204a6da9a1132577993eeecf0fb)
+---
+ arch/arm/boot/dts/bcm283x.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm283x.dtsi
++++ b/arch/arm/boot/dts/bcm283x.dtsi
+@@ -310,6 +310,14 @@
+ status = "disabled";
+ };
+
++ vec: vec@7e806000 {
++ compatible = "brcm,bcm2835-vec";
++ reg = <0x7e806000 0x1000>;
++ clocks = <&clocks BCM2835_CLOCK_VEC>;
++ interrupts = <2 27>;
++ status = "disabled";
++ };
++
+ pixelvalve@7e807000 {
+ compatible = "brcm,bcm2835-pixelvalve2";
+ reg = <0x7e807000 0x100>;
diff --git a/target/linux/brcm2708/patches-4.9/0175-ARM-dts-bcm283x-Enable-the-VEC-IP-on-all-RaspberryPi.patch b/target/linux/brcm2708/patches-4.9/0175-ARM-dts-bcm283x-Enable-the-VEC-IP-on-all-RaspberryPi.patch
new file mode 100644
index 0000000000..8689450266
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0175-ARM-dts-bcm283x-Enable-the-VEC-IP-on-all-RaspberryPi.patch
@@ -0,0 +1,26 @@
+From 686aed7763ddc3bd31b45454cbe73fb217a3d1c1 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@free-electrons.com>
+Date: Fri, 2 Dec 2016 14:48:13 +0100
+Subject: [PATCH] ARM: dts: bcm283x: Enable the VEC IP on all RaspberryPi
+ boards
+
+Enable the VEC IP on all RaspberryPi boards.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 5ab1a37c6027c114a87a1ae32cfc5ef303d643c5)
+---
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -92,3 +92,8 @@
+ &dsi1 {
+ power-domains = <&power RPI_POWER_DOMAIN_DSI1>;
+ };
++
++&vec {
++ power-domains = <&power RPI_POWER_DOMAIN_VEC>;
++ status = "okay";
++};
diff --git a/target/linux/brcm2708/patches-4.9/0176-BCM270X-Disable-VEC-unless-vc4-kms-v3d-is-present.patch b/target/linux/brcm2708/patches-4.9/0176-BCM270X-Disable-VEC-unless-vc4-kms-v3d-is-present.patch
new file mode 100644
index 0000000000..42c39650e7
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0176-BCM270X-Disable-VEC-unless-vc4-kms-v3d-is-present.patch
@@ -0,0 +1,37 @@
+From 323d84f926d907f424c3e55bec55ec84a9d04657 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 23 Jan 2017 11:41:54 -0800
+Subject: [PATCH] BCM270X: Disable VEC unless vc4-kms-v3d is present.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/bcm2708-rpi.dtsi | 4 ++++
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 7 +++++++
+ 2 files changed, 11 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2708-rpi.dtsi
+@@ -107,3 +107,7 @@
+ &usb {
+ power-domains = <&power RPI_POWER_DOMAIN_USB>;
+ };
++
++&vec {
++ status = "disabled";
++};
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
+@@ -148,6 +148,13 @@
+ };
+ };
+
++ fragment@18 {
++ target = <&vec>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
+ __overrides__ {
+ cma-256 = <0>,"+0-1-2-3-4";
+ cma-192 = <0>,"-0+1-2-3-4";
diff --git a/target/linux/brcm2708/patches-4.9/0177-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch b/target/linux/brcm2708/patches-4.9/0177-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch
new file mode 100644
index 0000000000..208ff58efb
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0177-drm-vc4-Name-the-primary-and-cursor-planes-in-fkms.patch
@@ -0,0 +1,24 @@
+From 789e1599cc6589b2a5c05c0f0bcd57fdaeb1b474 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 1 Feb 2017 17:09:18 -0800
+Subject: [PATCH] drm/vc4: Name the primary and cursor planes in fkms.
+
+This makes debugging nicer, compared to trying to remember what the
+IDs are.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -267,7 +267,7 @@ static struct drm_plane *vc4_fkms_plane_
+ ret = drm_universal_plane_init(dev, plane, 0xff,
+ &vc4_plane_funcs,
+ primary ? &xrgb8888 : &argb8888, 1,
+- type, NULL);
++ type, primary ? "primary" : "cursor");
+
+ if (type == DRM_PLANE_TYPE_PRIMARY) {
+ vc4_plane->fbinfo =
diff --git a/target/linux/brcm2708/patches-4.9/0178-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch b/target/linux/brcm2708/patches-4.9/0178-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch
new file mode 100644
index 0000000000..f3f141097b
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0178-drm-vc4-Add-DRM_DEBUG_ATOMIC-for-the-insides-of-fkms.patch
@@ -0,0 +1,69 @@
+From ac45ecdcbc38c6ec6b477980d0cd0760267f6057 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 1 Feb 2017 17:10:09 -0800
+Subject: [PATCH] drm/vc4: Add DRM_DEBUG_ATOMIC for the insides of fkms.
+
+Trying to debug weston on fkms involved figuring out what calls I was
+making to the firmware.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -102,6 +102,11 @@ static int vc4_plane_set_primary_blank(s
+ struct vc4_dev *vc4 = to_vc4_dev(plane->dev);
+
+ u32 packet = blank;
++
++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary plane %s",
++ plane->base.id, plane->name,
++ blank ? "blank" : "unblank");
++
+ return rpi_firmware_property(vc4->firmware,
+ RPI_FIRMWARE_FRAMEBUFFER_BLANK,
+ &packet, sizeof(packet));
+@@ -149,6 +154,16 @@ static void vc4_primary_plane_atomic_upd
+ WARN_ON_ONCE(vc4_plane->pitch != fb->pitches[0]);
+ }
+
++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] primary update %dx%d@%d +%d,%d 0x%08x/%d\n",
++ plane->base.id, plane->name,
++ state->crtc_w,
++ state->crtc_h,
++ bpp,
++ state->crtc_x,
++ state->crtc_y,
++ bo->paddr + fb->offsets[0],
++ fb->pitches[0]);
++
+ ret = rpi_firmware_transaction(vc4->firmware,
+ RPI_FIRMWARE_CHAN_FB,
+ vc4_plane->fbinfo_bus_addr);
+@@ -178,6 +193,15 @@ static void vc4_cursor_plane_atomic_upda
+ WARN_ON_ONCE(fb->pitches[0] != state->crtc_w * 4);
+ WARN_ON_ONCE(fb->bits_per_pixel != 32);
+
++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] update %dx%d cursor at %d,%d (0x%08x/%d)",
++ plane->base.id, plane->name,
++ state->crtc_w,
++ state->crtc_h,
++ state->crtc_x,
++ state->crtc_y,
++ bo->paddr + fb->offsets[0],
++ fb->pitches[0]);
++
+ ret = rpi_firmware_property(vc4->firmware,
+ RPI_FIRMWARE_SET_CURSOR_STATE,
+ &packet_state,
+@@ -200,6 +224,8 @@ static void vc4_cursor_plane_atomic_disa
+ u32 packet_state[] = { false, 0, 0, 0 };
+ int ret;
+
++ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] disabling cursor", plane->base.id, plane->name);
++
+ ret = rpi_firmware_property(vc4->firmware,
+ RPI_FIRMWARE_SET_CURSOR_STATE,
+ &packet_state,
diff --git a/target/linux/brcm2708/patches-4.9/0179-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch b/target/linux/brcm2708/patches-4.9/0179-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch
new file mode 100644
index 0000000000..73fbf2bc99
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0179-drm-vc4-Fix-sending-of-page-flip-completion-events-i.patch
@@ -0,0 +1,42 @@
+From bc93583742c7ba9c84462664d4c798ba43bef26f Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 2 Feb 2017 09:42:18 -0800
+Subject: [PATCH] drm/vc4: Fix sending of page flip completion events in FKMS
+ mode.
+
+In the rewrite of vc4_crtc.c for fkms, I dropped the part of the
+CRTC's atomic flush handler that moved the completion event from the
+proposed atomic state change to the CRTC's current state. That meant
+that when full screen pageflipping happened (glxgears -fullscreen in
+X, compton, por weston), the app would end up blocked firever waiting
+to draw its next frame.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -338,6 +338,21 @@ static int vc4_crtc_atomic_check(struct
+ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+ {
++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
++ struct drm_device *dev = crtc->dev;
++
++ if (crtc->state->event) {
++ unsigned long flags;
++
++ crtc->state->event->pipe = drm_crtc_index(crtc);
++
++ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
++
++ spin_lock_irqsave(&dev->event_lock, flags);
++ vc4_crtc->event = crtc->state->event;
++ crtc->state->event = NULL;
++ spin_unlock_irqrestore(&dev->event_lock, flags);
++ }
+ }
+
+ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
diff --git a/target/linux/brcm2708/patches-4.9/0180-drm-vc4-Fulfill-user-BO-creation-requests-from-the-k.patch b/target/linux/brcm2708/patches-4.9/0180-drm-vc4-Fulfill-user-BO-creation-requests-from-the-k.patch
new file mode 100644
index 0000000000..c0967b4639
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0180-drm-vc4-Fulfill-user-BO-creation-requests-from-the-k.patch
@@ -0,0 +1,53 @@
+From cb8a5a1cf8cfd5b88fe641ada9a2dfb318d43c3f Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Wed, 8 Feb 2017 15:00:54 -0800
+Subject: [PATCH] drm/vc4: Fulfill user BO creation requests from the kernel BO
+ cache.
+
+The from_cache flag was actually "the BO is invisible to userspace",
+so we can repurpose to just zero out a cached BO and return it to
+userspace.
+
+Improves wall time for a loop of 5 glsl-algebraic-add-add-1 by
+-1.44989% +/- 0.862891% (n=28, 1 outlier removed from each that
+appeared to be other system noise)
+
+Note that there's an intel-gpu-tools test to check for the proper
+zeroing behavior here, which we continue to pass.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/gpu/drm/vc4/vc4_bo.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_bo.c
++++ b/drivers/gpu/drm/vc4/vc4_bo.c
+@@ -208,21 +208,22 @@ struct drm_gem_object *vc4_create_object
+ }
+
+ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
+- bool from_cache)
++ bool allow_unzeroed)
+ {
+ size_t size = roundup(unaligned_size, PAGE_SIZE);
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct drm_gem_cma_object *cma_obj;
++ struct vc4_bo *bo;
+
+ if (size == 0)
+ return ERR_PTR(-EINVAL);
+
+ /* First, try to get a vc4_bo from the kernel BO cache. */
+- if (from_cache) {
+- struct vc4_bo *bo = vc4_bo_get_from_cache(dev, size);
+-
+- if (bo)
+- return bo;
++ bo = vc4_bo_get_from_cache(dev, size);
++ if (bo) {
++ if (!allow_unzeroed)
++ memset(bo->base.vaddr, 0, bo->base.base.size);
++ return bo;
+ }
+
+ cma_obj = drm_gem_cma_create(dev, size);
diff --git a/target/linux/brcm2708/patches-4.9/0181-drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-.patch b/target/linux/brcm2708/patches-4.9/0181-drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-.patch
new file mode 100644
index 0000000000..000f3a8df3
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0181-drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-.patch
@@ -0,0 +1,34 @@
+From 3f131f18e76bb3fa56158adea3abddeaac68e860 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Thu, 9 Feb 2017 09:23:34 -0800
+Subject: [PATCH] drm/vc4: Fix OOPSes from trying to cache a partially
+ constructed BO.
+
+If a CMA allocation failed, the partially constructed BO would be
+unreferenced through the normal path, and we might choose to put it in
+the BO cache. If we then reused it before it expired from the cache,
+the kernel would OOPS.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.")
+---
+ drivers/gpu/drm/vc4/vc4_bo.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_bo.c
++++ b/drivers/gpu/drm/vc4/vc4_bo.c
+@@ -314,6 +314,14 @@ void vc4_free_object(struct drm_gem_obje
+ goto out;
+ }
+
++ /* If this object was partially constructed but CMA allocation
++ * had failed, just free it.
++ */
++ if (!bo->base.vaddr) {
++ vc4_bo_destroy(bo);
++ goto out;
++ }
++
+ cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size);
+ if (!cache_list) {
+ vc4_bo_destroy(bo);
diff --git a/target/linux/brcm2708/patches-4.9/0182-drm-vc4-Verify-at-boot-that-CMA-doesn-t-cross-a-256M.patch b/target/linux/brcm2708/patches-4.9/0182-drm-vc4-Verify-at-boot-that-CMA-doesn-t-cross-a-256M.patch
new file mode 100644
index 0000000000..453d027ae9
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0182-drm-vc4-Verify-at-boot-that-CMA-doesn-t-cross-a-256M.patch
@@ -0,0 +1,79 @@
+From b280acf3c32746106c81419390f5b1869d644f66 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 12 Oct 2015 08:58:08 -0700
+Subject: [PATCH] drm/vc4: Verify at boot that CMA doesn't cross a 256MB
+ boundary.
+
+I've seen lots of users cranking CMA up higher, so throw an error if
+they do.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/base/dma-contiguous.c | 1 +
+ drivers/gpu/drm/vc4/vc4_v3d.c | 18 ++++++++++++++++++
+ mm/cma.c | 2 ++
+ 3 files changed, 21 insertions(+)
+
+--- a/drivers/base/dma-contiguous.c
++++ b/drivers/base/dma-contiguous.c
+@@ -35,6 +35,7 @@
+ #endif
+
+ struct cma *dma_contiguous_default_area;
++EXPORT_SYMBOL(dma_contiguous_default_area);
+
+ /*
+ * Default global CMA area size can be defined in kernel's .config.
+--- a/drivers/gpu/drm/vc4/vc4_v3d.c
++++ b/drivers/gpu/drm/vc4/vc4_v3d.c
+@@ -16,7 +16,10 @@
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
++#include "linux/init.h"
++#include "linux/cma.h"
+ #include "linux/component.h"
++#include "linux/dma-contiguous.h"
+ #include "linux/pm_runtime.h"
+ #include "vc4_drv.h"
+ #include "vc4_regs.h"
+@@ -185,8 +188,23 @@ static int vc4_v3d_bind(struct device *d
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+ struct vc4_v3d *v3d = NULL;
++ struct cma *cma;
+ int ret;
+
++ cma = dev_get_cma_area(dev);
++ if (!cma)
++ return -EINVAL;
++
++ if ((cma_get_base(cma) & 0xf0000000) !=
++ ((cma_get_base(cma) + cma_get_size(cma) - 1) & 0xf0000000)) {
++ DRM_ERROR("V3D requires that the CMA area (0x%08lx - 0x%08lx) "
++ "not span a 256MB boundary, or memory corruption "
++ "would happen.\n",
++ (long)cma_get_base(cma),
++ cma_get_base(cma) + cma_get_size(cma));
++ return -EINVAL;
++ }
++
+ v3d = devm_kzalloc(&pdev->dev, sizeof(*v3d), GFP_KERNEL);
+ if (!v3d)
+ return -ENOMEM;
+--- a/mm/cma.c
++++ b/mm/cma.c
+@@ -47,11 +47,13 @@ phys_addr_t cma_get_base(const struct cm
+ {
+ return PFN_PHYS(cma->base_pfn);
+ }
++EXPORT_SYMBOL(cma_get_base);
+
+ unsigned long cma_get_size(const struct cma *cma)
+ {
+ return cma->count << PAGE_SHIFT;
+ }
++EXPORT_SYMBOL(cma_get_size);
+
+ static unsigned long cma_bitmap_aligned_mask(const struct cma *cma,
+ int align_order)
diff --git a/target/linux/brcm2708/patches-4.9/0183-BCM270X_DT-Add-SMSC-ethernet-controller-to-DT.patch b/target/linux/brcm2708/patches-4.9/0183-BCM270X_DT-Add-SMSC-ethernet-controller-to-DT.patch
new file mode 100644
index 0000000000..76b1bf3bbf
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0183-BCM270X_DT-Add-SMSC-ethernet-controller-to-DT.patch
@@ -0,0 +1,57 @@
+From 35a2c1524b21318228f0566d9a4ac53bf3138bdc Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 17 Feb 2017 09:47:11 +0000
+Subject: [PATCH] BCM270X_DT: Add SMSC ethernet controller to DT
+
+With an ethernet node in the DT, a suitable firmware can populate the
+local-mac-address property, removing the need for a downstream patch
+to the driver to read its MAC address from a module parameter.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 +
+ arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 +
+ arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 +
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 1 +
+ 4 files changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts
+@@ -1,6 +1,7 @@
+ /dts-v1/;
+
+ #include "bcm2708.dtsi"
++#include "bcm283x-rpi-smsc9514.dtsi"
+
+ / {
+ model = "Raspberry Pi Model B+";
+--- a/arch/arm/boot/dts/bcm2708-rpi-b.dts
++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts
+@@ -1,6 +1,7 @@
+ /dts-v1/;
+
+ #include "bcm2708.dtsi"
++#include "bcm283x-rpi-smsc9512.dtsi"
+
+ / {
+ model = "Raspberry Pi Model B";
+--- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts
+@@ -1,6 +1,7 @@
+ /dts-v1/;
+
+ #include "bcm2709.dtsi"
++#include "bcm283x-rpi-smsc9514.dtsi"
+
+ / {
+ model = "Raspberry Pi 2 Model B";
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -5,6 +5,7 @@
+ #endif
+
+ #include "bcm2710.dtsi"
++#include "bcm283x-rpi-smsc9514.dtsi"
+
+ / {
+ model = "Raspberry Pi 3 Model B";
diff --git a/target/linux/brcm2708/patches-4.9/0185-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch b/target/linux/brcm2708/patches-4.9/0185-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch
new file mode 100644
index 0000000000..13f6c11f59
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0185-clk-bcm2835-Mark-used-PLLs-and-dividers-CRITICAL.patch
@@ -0,0 +1,28 @@
+From a2ca8b47db0d08735e1c0ebeaf34e88522091662 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 13 Feb 2017 17:20:08 +0000
+Subject: [PATCH] clk-bcm2835: Mark used PLLs and dividers CRITICAL
+
+The VPU configures and relies on several PLLs and dividers. Mark all
+enabled dividers and their PLLs as CRITICAL to prevent the kernel from
+switching them off.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/clk/bcm/clk-bcm2835.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1366,6 +1366,11 @@ bcm2835_register_pll_divider(struct bcm2
+ divider->div.hw.init = &init;
+ divider->div.table = NULL;
+
++ if (!(cprman_read(cprman, data->cm_reg) & data->hold_mask)) {
++ init.flags |= CLK_IS_CRITICAL;
++ divider->div.flags |= CLK_IS_CRITICAL;
++ }
++
+ divider->cprman = cprman;
+ divider->data = data;
+
diff --git a/target/linux/brcm2708/patches-4.9/0186-clk-bcm2835-Add-claim-clocks-property.patch b/target/linux/brcm2708/patches-4.9/0186-clk-bcm2835-Add-claim-clocks-property.patch
new file mode 100644
index 0000000000..09dcfa7a68
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0186-clk-bcm2835-Add-claim-clocks-property.patch
@@ -0,0 +1,133 @@
+From 5c1128ebe6c7a4af3f1784a640df7f3698233e9d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 13 Feb 2017 17:20:08 +0000
+Subject: [PATCH] clk-bcm2835: Add claim-clocks property
+
+The claim-clocks property can be used to prevent PLLs and dividers
+from being marked as critical. It contains a vector of clock IDs,
+as defined by dt-bindings/clock/bcm2835.h.
+
+Use this mechanism to claim PLLD_DSI0, PLLD_DSI1, PLLH_AUX and
+PLLH_PIX for the vc4_kms_v3d driver.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 14 +++++++++
+ drivers/clk/bcm/clk-bcm2835.c | 34 ++++++++++++++++++++--
+ 2 files changed, 46 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
++++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts
+@@ -5,6 +5,8 @@
+ /dts-v1/;
+ /plugin/;
+
++#include <dt-bindings/clock/bcm2835.h>
++
+ / {
+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
+
+@@ -155,6 +157,18 @@
+ };
+ };
+
++ fragment@19 {
++ target = <&clocks>;
++ __overlay__ {
++ claim-clocks = <
++ BCM2835_PLLD_DSI0
++ BCM2835_PLLD_DSI1
++ BCM2835_PLLH_AUX
++ BCM2835_PLLH_PIX
++ >;
++ };
++ };
++
+ __overrides__ {
+ cma-256 = <0>,"+0-1-2-3-4";
+ cma-192 = <0>,"-0+1-2-3-4";
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1298,6 +1298,8 @@ static const struct clk_ops bcm2835_vpu_
+ .debug_init = bcm2835_clock_debug_init,
+ };
+
++static bool bcm2835_clk_is_claimed(const char *name);
++
+ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
+ const struct bcm2835_pll_data *data)
+ {
+@@ -1314,6 +1316,9 @@ static struct clk_hw *bcm2835_register_p
+ init.ops = &bcm2835_pll_clk_ops;
+ init.flags = CLK_IGNORE_UNUSED;
+
++ if (!bcm2835_clk_is_claimed(data->name))
++ init.flags |= CLK_IS_CRITICAL;
++
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return NULL;
+@@ -1367,8 +1372,10 @@ bcm2835_register_pll_divider(struct bcm2
+ divider->div.table = NULL;
+
+ if (!(cprman_read(cprman, data->cm_reg) & data->hold_mask)) {
+- init.flags |= CLK_IS_CRITICAL;
+- divider->div.flags |= CLK_IS_CRITICAL;
++ if (!bcm2835_clk_is_claimed(data->source_pll))
++ init.flags |= CLK_IS_CRITICAL;
++ if (!bcm2835_clk_is_claimed(data->name))
++ divider->div.flags |= CLK_IS_CRITICAL;
+ }
+
+ divider->cprman = cprman;
+@@ -2104,6 +2111,8 @@ static const struct bcm2835_clk_desc clk
+ .ctl_reg = CM_PERIICTL),
+ };
+
++static bool bcm2835_clk_claimed[ARRAY_SIZE(clk_desc_array)];
++
+ /*
+ * Permanently take a reference on the parent of the SDRAM clock.
+ *
+@@ -2123,6 +2132,19 @@ static int bcm2835_mark_sdc_parent_criti
+ return clk_prepare_enable(parent);
+ }
+
++static bool bcm2835_clk_is_claimed(const char *name)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(clk_desc_array); i++) {
++ const char *clk_name = *(const char **)(clk_desc_array[i].data);
++ if (!strcmp(name, clk_name))
++ return bcm2835_clk_claimed[i];
++ }
++
++ return false;
++}
++
+ static int bcm2835_clk_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -2132,6 +2154,7 @@ static int bcm2835_clk_probe(struct plat
+ const struct bcm2835_clk_desc *desc;
+ const size_t asize = ARRAY_SIZE(clk_desc_array);
+ size_t i;
++ u32 clk_id;
+ int ret;
+
+ cprman = devm_kzalloc(dev, sizeof(*cprman) +
+@@ -2147,6 +2170,13 @@ static int bcm2835_clk_probe(struct plat
+ if (IS_ERR(cprman->regs))
+ return PTR_ERR(cprman->regs);
+
++ memset(bcm2835_clk_claimed, 0, sizeof(bcm2835_clk_claimed));
++ for (i = 0;
++ !of_property_read_u32_index(pdev->dev.of_node, "claim-clocks",
++ i, &clk_id);
++ i++)
++ bcm2835_clk_claimed[clk_id]= true;
++
+ memcpy(cprman->real_parent_names, cprman_parent_names,
+ sizeof(cprman_parent_names));
+ of_clk_parent_fill(dev->of_node, cprman->real_parent_names,
diff --git a/target/linux/brcm2708/patches-4.9/0187-dmaengine-bcm2835-Fix-cyclic-DMA-period-splitting.patch b/target/linux/brcm2708/patches-4.9/0187-dmaengine-bcm2835-Fix-cyclic-DMA-period-splitting.patch
new file mode 100644
index 0000000000..fa0d998a2d
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0187-dmaengine-bcm2835-Fix-cyclic-DMA-period-splitting.patch
@@ -0,0 +1,39 @@
+From 9fd7a158ec098ab05b8d3ec2c2973b3dc7e498f3 Mon Sep 17 00:00:00 2001
+From: Matthias Reichl <hias@horus.com>
+Date: Mon, 20 Feb 2017 20:01:16 +0100
+Subject: [PATCH] dmaengine: bcm2835: Fix cyclic DMA period splitting
+
+The code responsible for splitting periods into chunks that
+can be handled by the DMA controller missed to update total_len,
+the number of bytes processed in the current period, when there
+are more chunks to follow.
+
+Therefore total_len was stuck at 0 and the code didn't work at all.
+This resulted in a wrong control block layout and audio issues because
+the cyclic DMA callback wasn't executing on period boundaries.
+
+Fix this by adding the missing total_len update.
+
+Signed-off-by: Matthias Reichl <hias@horus.com>
+Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
+Tested-by: Clive Messer <clive.messer@digitaldreamtime.co.uk>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+---
+ drivers/dma/bcm2835-dma.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/bcm2835-dma.c
++++ b/drivers/dma/bcm2835-dma.c
+@@ -253,8 +253,11 @@ static void bcm2835_dma_create_cb_set_le
+ */
+
+ /* have we filled in period_length yet? */
+- if (*total_len + control_block->length < period_len)
++ if (*total_len + control_block->length < period_len) {
++ /* update number of bytes in this period so far */
++ *total_len += control_block->length;
+ return;
++ }
+
+ /* calculate the length that remains to reach period_length */
+ control_block->length = period_len - *total_len;
diff --git a/target/linux/brcm2708/patches-4.9/0188-Add-ads1015-driver-to-config.patch b/target/linux/brcm2708/patches-4.9/0188-Add-ads1015-driver-to-config.patch
new file mode 100644
index 0000000000..1303bdc101
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0188-Add-ads1015-driver-to-config.patch
@@ -0,0 +1,52 @@
+From 9e638878dd33652b34e51746d369afba6103d77e Mon Sep 17 00:00:00 2001
+From: Scott Ellis <scott@jumpnowtek.com>
+Date: Thu, 23 Feb 2017 11:56:20 -0500
+Subject: [PATCH] Add ads1015 driver to config
+
+---
+ arch/arm/configs/bcm2709_defconfig | 3 ++-
+ arch/arm/configs/bcmrpi_defconfig | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -653,6 +653,7 @@ CONFIG_HWMON=m
+ CONFIG_SENSORS_LM75=m
+ CONFIG_SENSORS_SHT21=m
+ CONFIG_SENSORS_SHTC1=m
++CONFIG_SENSORS_ADS1015=m
+ CONFIG_SENSORS_INA2XX=m
+ CONFIG_THERMAL=y
+ CONFIG_THERMAL_BCM2835=y
+@@ -833,9 +834,9 @@ CONFIG_VIDEO_OV7640=m
+ CONFIG_VIDEO_MT9V011=m
+ CONFIG_DRM=m
+ CONFIG_DRM_LOAD_EDID_FIRMWARE=y
++CONFIG_DRM_UDL=m
+ CONFIG_DRM_PANEL_SIMPLE=m
+ CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
+-CONFIG_DRM_UDL=m
+ CONFIG_DRM_VC4=m
+ CONFIG_FB=y
+ CONFIG_FB_BCM2708=y
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -647,6 +647,7 @@ CONFIG_HWMON=m
+ CONFIG_SENSORS_LM75=m
+ CONFIG_SENSORS_SHT21=m
+ CONFIG_SENSORS_SHTC1=m
++CONFIG_SENSORS_ADS1015=m
+ CONFIG_SENSORS_INA2XX=m
+ CONFIG_THERMAL=y
+ CONFIG_THERMAL_BCM2835=y
+@@ -827,9 +828,9 @@ CONFIG_VIDEO_OV7640=m
+ CONFIG_VIDEO_MT9V011=m
+ CONFIG_DRM=m
+ CONFIG_DRM_LOAD_EDID_FIRMWARE=y
++CONFIG_DRM_UDL=m
+ CONFIG_DRM_PANEL_SIMPLE=m
+ CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
+-CONFIG_DRM_UDL=m
+ CONFIG_DRM_VC4=m
+ CONFIG_FB=y
+ CONFIG_FB_BCM2708=y
diff --git a/target/linux/brcm2708/patches-4.9/0189-config-add-slcan-kernel-module.patch b/target/linux/brcm2708/patches-4.9/0189-config-add-slcan-kernel-module.patch
new file mode 100644
index 0000000000..021eb014c8
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0189-config-add-slcan-kernel-module.patch
@@ -0,0 +1,31 @@
+From 2fd423706eb3afde2a36845488e18d194b18b0c6 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 27 Jan 2017 18:49:30 +0000
+Subject: [PATCH] config: add slcan kernel module
+
+See: https://github.com/raspberrypi/linux/issues/1819
+---
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -361,6 +361,7 @@ CONFIG_BAYCOM_SER_HDX=m
+ CONFIG_YAM=m
+ CONFIG_CAN=m
+ CONFIG_CAN_VCAN=m
++CONFIG_CAN_SLCAN=m
+ CONFIG_CAN_MCP251X=m
+ CONFIG_IRDA=m
+ CONFIG_IRLAN=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -357,6 +357,7 @@ CONFIG_BAYCOM_SER_HDX=m
+ CONFIG_YAM=m
+ CONFIG_CAN=m
+ CONFIG_CAN_VCAN=m
++CONFIG_CAN_SLCAN=m
+ CONFIG_CAN_MCP251X=m
+ CONFIG_IRDA=m
+ CONFIG_IRLAN=m
diff --git a/target/linux/brcm2708/patches-4.9/0190-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch b/target/linux/brcm2708/patches-4.9/0190-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch
new file mode 100644
index 0000000000..eb6422a469
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0190-sound-Support-for-Dion-Audio-LOCO-V2-DAC-AMP-HAT.patch
@@ -0,0 +1,251 @@
+From a20dbe4972ea3df27f24c5397102e1346462a4f4 Mon Sep 17 00:00:00 2001
+From: Miquel <miquelblauw@hotmail.com>
+Date: Fri, 24 Feb 2017 20:51:06 +0100
+Subject: [PATCH] sound: Support for Dion Audio LOCO-V2 DAC-AMP HAT
+
+Signed-off-by: Miquel Blauw <info@dionaudio.nl>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 19 +++++
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ sound/soc/bcm/Kconfig | 7 ++
+ sound/soc/bcm/Makefile | 2 +
+ sound/soc/bcm/dionaudio_loco-v2.c | 140 ++++++++++++++++++++++++++++++++++++
+ 7 files changed, 171 insertions(+)
+ create mode 100644 sound/soc/bcm/dionaudio_loco-v2.c
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -13,6 +13,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ bmp085_i2c-sensor.dtbo \
+ dht11.dtbo \
+ dionaudio-loco.dtbo \
++ dionaudio-loco-v2.dtbo \
+ dpi18.dtbo \
+ dpi24.dtbo \
+ dwc-otg.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -308,6 +308,25 @@ Load: dtoverlay=dionaudio-loco
+ Params: <None>
+
+
++Name: dionaudio-loco-v2
++Info: Configures the Dion Audio LOCO-V2 DAC-AMP
++Load: dtoverlay=dionaudio-loco-v2,<param>=<val>
++Params: 24db_digital_gain Allow gain to be applied via the PCM512x codec
++ Digital volume control. Enable with
++ "dtoverlay=hifiberry-dacplus,24db_digital_gain"
++ (The default behaviour is that the Digital
++ volume control is limited to a maximum of
++ 0dB. ie. it can attenuate but not provide
++ gain. For most users, this will be desired
++ as it will prevent clipping. By appending
++ the 24dB_digital_gain parameter, the Digital
++ volume control will allow up to 24dB of
++ gain. If this parameter is enabled, it is the
++ responsibility of the user to ensure that
++ the Digital volume control is set to a value
++ that does not result in clipping/distortion!)
++
++
+ Name: dpi18
+ Info: Overlay for a generic 18-bit DPI display
+ This uses GPIOs 0-21 (so no I2C, uart etc.), and activates the output
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -889,6 +889,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
+ CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
+ CONFIG_SND_DIGIDAC1_SOUNDCARD=m
+ CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
++CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
+ CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
+ CONFIG_SND_PISOUND=m
+ CONFIG_SND_SOC_ADAU1701=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -883,6 +883,7 @@ CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
+ CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
+ CONFIG_SND_DIGIDAC1_SOUNDCARD=m
+ CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
++CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
+ CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
+ CONFIG_SND_PISOUND=m
+ CONFIG_SND_SOC_ADAU1701=m
+--- a/sound/soc/bcm/Kconfig
++++ b/sound/soc/bcm/Kconfig
+@@ -133,6 +133,13 @@ config SND_BCM2708_SOC_DIONAUDIO_LOCO
+ help
+ Say Y or M if you want to add support for Dion Audio LOCO.
+
++config SND_BCM2708_SOC_DIONAUDIO_LOCO_V2
++ tristate "Support for Dion Audio LOCO-V2 DAC-AMP"
++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
++ select SND_SOC_PCM5122
++ help
++ Say Y or M if you want to add support for Dion Audio LOCO-V2.
++
+ config SND_BCM2708_SOC_ALLO_PIANO_DAC
+ tristate "Support for Allo Piano DAC"
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+--- a/sound/soc/bcm/Makefile
++++ b/sound/soc/bcm/Makefile
+@@ -25,6 +25,7 @@ snd-soc-raspidac3-objs := raspidac3.o
+ snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
+ snd-soc-digidac1-soundcard-objs := digidac1-soundcard.o
+ snd-soc-dionaudio-loco-objs := dionaudio_loco.o
++snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o
+ snd-soc-allo-piano-dac-objs := allo-piano-dac.o
+ snd-soc-pisound-objs := pisound.o
+
+@@ -44,5 +45,6 @@ obj-$(CONFIG_SND_BCM2708_SOC_RASPIDAC3)
+ obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
+ obj-$(CONFIG_SND_DIGIDAC1_SOUNDCARD) += snd-soc-digidac1-soundcard.o
+ obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO) += snd-soc-dionaudio-loco.o
++obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o
+ obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o
+ obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o
+--- /dev/null
++++ b/sound/soc/bcm/dionaudio_loco-v2.c
+@@ -0,0 +1,140 @@
++/*
++ * ASoC Driver for Dion Audio LOCO-V2 DAC-AMP
++ *
++ * Author: Miquel Blauw <info@dionaudio.nl>
++ * Copyright 2017
++ *
++ * Based on the software of the RPi-DAC writen by Florian Meier
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/jack.h>
++
++static bool digital_gain_0db_limit = true;
++
++static int snd_rpi_dionaudio_loco_v2_init(struct snd_soc_pcm_runtime *rtd)
++{
++ if (digital_gain_0db_limit) {
++ int ret;
++ struct snd_soc_card *card = rtd->card;
++
++ ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207);
++ if (ret < 0)
++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret);
++ }
++
++ return 0;
++}
++
++static int snd_rpi_dionaudio_loco_v2_hw_params(
++ struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++
++ unsigned int sample_bits =
++ snd_pcm_format_physical_width(params_format(params));
++
++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
++}
++
++/* machine stream operations */
++static struct snd_soc_ops snd_rpi_dionaudio_loco_v2_ops = {
++ .hw_params = snd_rpi_dionaudio_loco_v2_hw_params,
++};
++
++static struct snd_soc_dai_link snd_rpi_dionaudio_loco_v2_dai[] = {
++{
++ .name = "DionAudio LOCO-V2",
++ .stream_name = "DionAudio LOCO-V2 DAC-AMP",
++ .cpu_dai_name = "bcm2708-i2s.0",
++ .codec_dai_name = "pcm512x-hifi",
++ .platform_name = "bcm2708-i2s.0",
++ .codec_name = "pcm512x.1-004d",
++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBS_CFS,
++ .ops = &snd_rpi_dionaudio_loco_v2_ops,
++ .init = snd_rpi_dionaudio_loco_v2_init,
++},};
++
++/* audio machine driver */
++static struct snd_soc_card snd_rpi_dionaudio_loco_v2 = {
++ .name = "Dion Audio LOCO-V2",
++ .dai_link = snd_rpi_dionaudio_loco_v2_dai,
++ .num_links = ARRAY_SIZE(snd_rpi_dionaudio_loco_v2_dai),
++};
++
++static int snd_rpi_dionaudio_loco_v2_probe(struct platform_device *pdev)
++{
++ int ret = 0;
++
++ snd_rpi_dionaudio_loco_v2.dev = &pdev->dev;
++
++ if (pdev->dev.of_node) {
++ struct device_node *i2s_node;
++ struct snd_soc_dai_link *dai =
++ &snd_rpi_dionaudio_loco_v2_dai[0];
++
++ i2s_node = of_parse_phandle(pdev->dev.of_node,
++ "i2s-controller", 0);
++ if (i2s_node) {
++ dai->cpu_dai_name = NULL;
++ dai->cpu_of_node = i2s_node;
++ dai->platform_name = NULL;
++ dai->platform_of_node = i2s_node;
++ }
++
++ digital_gain_0db_limit = !of_property_read_bool(
++ pdev->dev.of_node, "dionaudio,24db_digital_gain");
++ }
++
++ ret = snd_soc_register_card(&snd_rpi_dionaudio_loco_v2);
++ if (ret)
++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
++ ret);
++
++ return ret;
++}
++
++static int snd_rpi_dionaudio_loco_v2_remove(struct platform_device *pdev)
++{
++ return snd_soc_unregister_card(&snd_rpi_dionaudio_loco_v2);
++}
++
++static const struct of_device_id dionaudio_of_match[] = {
++ { .compatible = "dionaudio,dionaudio-loco-v2", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, dionaudio_of_match);
++
++static struct platform_driver snd_rpi_dionaudio_loco_v2_driver = {
++ .driver = {
++ .name = "snd-rpi-dionaudio-loco-v2",
++ .owner = THIS_MODULE,
++ .of_match_table = dionaudio_of_match,
++ },
++ .probe = snd_rpi_dionaudio_loco_v2_probe,
++ .remove = snd_rpi_dionaudio_loco_v2_remove,
++};
++
++module_platform_driver(snd_rpi_dionaudio_loco_v2_driver);
++
++MODULE_AUTHOR("Miquel Blauw <info@dionaudio.nl>");
++MODULE_DESCRIPTION("ASoC Driver for DionAudio LOCO-V2");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/brcm2708/patches-4.9/0191-SQUASH-Add-LOCO-V2-overlay-from-last-commit.patch b/target/linux/brcm2708/patches-4.9/0191-SQUASH-Add-LOCO-V2-overlay-from-last-commit.patch
new file mode 100644
index 0000000000..be3618a0bf
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0191-SQUASH-Add-LOCO-V2-overlay-from-last-commit.patch
@@ -0,0 +1,62 @@
+From e3b5ca5cb69c36f41436ab8be96710e39442ce28 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Sun, 26 Feb 2017 01:13:02 +0000
+Subject: [PATCH] SQUASH: Add LOCO-V2 overlay from last commit
+
+---
+ .../dts/overlays/dionaudio-loco-v2-overlay.dts | 49 ++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts
+
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/dionaudio-loco-v2-overlay.dts
+@@ -0,0 +1,49 @@
++/*
++ * Definitions for Dion Audio LOCO-V2 DAC-AMP
++ * eg. dtoverlay=dionaudio-loco-v2
++ *
++ * PCM5242 DAC (in software mode) and TPA3255 AMP.
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2708";
++
++ fragment@0 {
++ target = <&sound>;
++ frag0: __overlay__ {
++ compatible = "dionaudio,dionaudio-loco-v2";
++ i2s-controller = <&i2s>;
++ status = "okay";
++ };
++ };
++
++ fragment@1 {
++ target = <&i2s>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@2 {
++ target = <&i2c1>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ pcm5122@4c {
++ #sound-dai-cells = <0>;
++ compatible = "ti,pcm5122";
++ reg = <0x4d>;
++ status = "okay";
++ };
++ };
++ };
++
++ __overrides__ {
++ 24db_digital_gain = <&frag0>,"dionaudio,24db_digital_gain?";
++ };
++};
diff --git a/target/linux/brcm2708/patches-4.9/0192-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch b/target/linux/brcm2708/patches-4.9/0192-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch
new file mode 100644
index 0000000000..262dc14bce
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0192-Add-support-for-Fe-Pi-audio-sound-card.-1867.patch
@@ -0,0 +1,333 @@
+From c646d023c75607a9ebc7296fe424d6eb4e804164 Mon Sep 17 00:00:00 2001
+From: Fe-Pi <fe-pi@cox.net>
+Date: Wed, 1 Mar 2017 04:42:43 -0700
+Subject: [PATCH] Add support for Fe-Pi audio sound card. (#1867)
+
+Fe-Pi Audio Sound Card is based on NXP SGTL5000 codec.
+Mechanical specification of the board is the same the Raspberry Pi Zero.
+3.5mm jacks for Headphone/Mic, Line In, and Line Out.
+
+Signed-off-by: Henry Kupis <fe-pi@cox.net>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 6 +
+ arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts | 70 +++++++++
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ sound/soc/bcm/Kconfig | 7 +
+ sound/soc/bcm/Makefile | 2 +
+ sound/soc/bcm/fe-pi-audio.c | 158 +++++++++++++++++++++
+ 8 files changed, 246 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts
+ create mode 100644 sound/soc/bcm/fe-pi-audio.c
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -20,6 +20,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ dwc2.dtbo \
+ enc28j60.dtbo \
+ enc28j60-spi2.dtbo \
++ fe-pi-audio.dtbo \
+ gpio-ir.dtbo \
+ gpio-poweroff.dtbo \
+ hifiberry-amp.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -383,6 +383,12 @@ Params: int_pin GPIO use
+ speed SPI bus speed (default 12000000)
+
+
++Name: fe-pi-audio
++Info: Configures the Fe-Pi Audio Sound Card
++Load: dtoverlay=fe-pi-audio
++Params: <None>
++
++
+ Name: gpio-ir
+ Info: Use GPIO pin as rc-core style infrared receiver input. The rc-core-
+ based gpio_ir_recv driver maps received keys directly to a
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/fe-pi-audio-overlay.dts
+@@ -0,0 +1,70 @@
++// Definitions for Fe-Pi Audio
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2708";
++
++ fragment@0 {
++ target = <&clocks>;
++ __overlay__ {
++ sgtl5000_mclk: sgtl5000_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <12288000>;
++ clock-output-names = "sgtl5000-mclk";
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&soc>;
++ __overlay__ {
++ reg_1v8: reg_1v8@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "1V8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&i2c1>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ sgtl5000@0a {
++ #sound-dai-cells = <0>;
++ compatible = "fepi,sgtl5000";
++ reg = <0x0a>;
++ clocks = <&sgtl5000_mclk>;
++ micbias-resistor-k-ohms = <2>;
++ micbias-voltage-m-volts = <3000>;
++ VDDA-supply = <&vdd_3v3_reg>;
++ VDDIO-supply = <&vdd_3v3_reg>;
++ VDDD-supply = <&reg_1v8>;
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@3 {
++ target = <&i2s>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@4 {
++ target = <&sound>;
++ __overlay__ {
++ compatible = "fe-pi,fe-pi-audio";
++ i2s-controller = <&i2s>;
++ status = "okay";
++ };
++ };
++};
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -891,6 +891,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m
+ CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
+ CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
+ CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m
+ CONFIG_SND_PISOUND=m
+ CONFIG_SND_SOC_ADAU1701=m
+ CONFIG_SND_SOC_ADAU7002=m
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -885,6 +885,7 @@ CONFIG_SND_DIGIDAC1_SOUNDCARD=m
+ CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
+ CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
+ CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
++CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m
+ CONFIG_SND_PISOUND=m
+ CONFIG_SND_SOC_ADAU1701=m
+ CONFIG_SND_SOC_ADAU7002=m
+--- a/sound/soc/bcm/Kconfig
++++ b/sound/soc/bcm/Kconfig
+@@ -147,6 +147,13 @@ config SND_BCM2708_SOC_ALLO_PIANO_DAC
+ help
+ Say Y or M if you want to add support for Allo Piano DAC.
+
++config SND_BCM2708_SOC_FE_PI_AUDIO
++ tristate "Support for Fe-Pi-Audio"
++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
++ select SND_SOC_SGTL5000
++ help
++ Say Y or M if you want to add support for Fe-Pi-Audio.
++
+ config SND_PISOUND
+ tristate "Support for Blokas Labs pisound"
+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
+--- a/sound/soc/bcm/Makefile
++++ b/sound/soc/bcm/Makefile
+@@ -28,6 +28,7 @@ snd-soc-dionaudio-loco-objs := dionaudio
+ snd-soc-dionaudio-loco-v2-objs := dionaudio_loco-v2.o
+ snd-soc-allo-piano-dac-objs := allo-piano-dac.o
+ snd-soc-pisound-objs := pisound.o
++snd-soc-fe-pi-audio-objs := fe-pi-audio.o
+
+ obj-$(CONFIG_SND_BCM2708_SOC_ADAU1977_ADC) += snd-soc-adau1977-adc.o
+ obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o
+@@ -48,3 +49,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_L
+ obj-$(CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2) += snd-soc-dionaudio-loco-v2.o
+ obj-$(CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC) += snd-soc-allo-piano-dac.o
+ obj-$(CONFIG_SND_PISOUND) += snd-soc-pisound.o
++obj-$(CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO) += snd-soc-fe-pi-audio.o
+--- /dev/null
++++ b/sound/soc/bcm/fe-pi-audio.c
+@@ -0,0 +1,158 @@
++/*
++ * ASoC Driver for Fe-Pi Audio Sound Card
++ *
++ * Author: Henry Kupis <kuupaz@gmail.com>
++ * Copyright 2016
++ * based on code by Florian Meier <florian.meier@koalo.de>
++ * based on code by Shawn Guo <shawn.guo@linaro.org>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/io.h>
++
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/jack.h>
++
++#include "../codecs/sgtl5000.h"
++
++static int snd_fe_pi_audio_init(struct snd_soc_pcm_runtime *rtd)
++{
++ struct snd_soc_card *card = rtd->card;
++ struct snd_soc_codec *codec = rtd->codec;
++
++ snd_soc_dapm_force_enable_pin(&card->dapm, "LO");
++ snd_soc_dapm_force_enable_pin(&card->dapm, "ADC");
++ snd_soc_dapm_force_enable_pin(&card->dapm, "DAC");
++ snd_soc_dapm_force_enable_pin(&card->dapm, "HP");
++ snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
++ SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
++
++ return 0;
++}
++
++static int snd_fe_pi_audio_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct device *dev = rtd->card->dev;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++
++ int ret;
++
++ /* Set SGTL5000's SYSCLK */
++ ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, 12288000, SND_SOC_CLOCK_IN);
++ if (ret) {
++ dev_err(dev, "could not set codec driver clock params\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++
++static struct snd_soc_ops snd_fe_pi_audio_ops = {
++ .hw_params = snd_fe_pi_audio_hw_params,
++};
++
++static struct snd_soc_dai_link snd_fe_pi_audio_dai[] = {
++ {
++ .name = "FE-PI",
++ .stream_name = "Fe-Pi HiFi",
++ .cpu_dai_name = "bcm2708-i2s.0",
++ .codec_dai_name = "sgtl5000",
++ .platform_name = "bcm2708-i2s.0",
++ .codec_name = "sgtl5000.1-000a",
++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBM_CFM,
++ .ops = &snd_fe_pi_audio_ops,
++ .init = snd_fe_pi_audio_init,
++ },
++};
++
++static const struct snd_soc_dapm_route fe_pi_audio_dapm_routes[] = {
++ {"ADC", NULL, "Mic Bias"},
++};
++
++
++static struct snd_soc_card fe_pi_audio = {
++ .name = "Fe-Pi Audio",
++ .owner = THIS_MODULE,
++ .dai_link = snd_fe_pi_audio_dai,
++ .num_links = ARRAY_SIZE(snd_fe_pi_audio_dai),
++
++ .dapm_routes = fe_pi_audio_dapm_routes,
++ .num_dapm_routes = ARRAY_SIZE(fe_pi_audio_dapm_routes),
++};
++
++static int snd_fe_pi_audio_probe(struct platform_device *pdev)
++{
++ int ret = 0;
++ struct snd_soc_card *card = &fe_pi_audio;
++ struct device_node *np = pdev->dev.of_node;
++ struct device_node *i2s_node;
++ struct snd_soc_dai_link *dai = &snd_fe_pi_audio_dai[0];
++
++ fe_pi_audio.dev = &pdev->dev;
++
++ i2s_node = of_parse_phandle(np, "i2s-controller", 0);
++ if (!i2s_node) {
++ dev_err(&pdev->dev, "i2s_node phandle missing or invalid\n");
++ return -EINVAL;
++ }
++
++ dai->cpu_dai_name = NULL;
++ dai->cpu_of_node = i2s_node;
++ dai->platform_name = NULL;
++ dai->platform_of_node = i2s_node;
++
++ of_node_put(i2s_node);
++
++ card->dev = &pdev->dev;
++ platform_set_drvdata(pdev, card);
++
++ ret = snd_soc_register_card(card);
++ if (ret && ret != -EPROBE_DEFER)
++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret);
++
++ return ret;
++}
++
++static int snd_fe_pi_audio_remove(struct platform_device *pdev)
++{
++ return snd_soc_unregister_card(&fe_pi_audio);
++}
++
++static const struct of_device_id snd_fe_pi_audio_of_match[] = {
++ { .compatible = "fe-pi,fe-pi-audio", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, snd_fe_pi_audio_of_match);
++
++static struct platform_driver snd_fe_pi_audio_driver = {
++ .driver = {
++ .name = "snd-fe-pi-audio",
++ .owner = THIS_MODULE,
++ .of_match_table = snd_fe_pi_audio_of_match,
++ },
++ .probe = snd_fe_pi_audio_probe,
++ .remove = snd_fe_pi_audio_remove,
++};
++
++module_platform_driver(snd_fe_pi_audio_driver);
++
++MODULE_AUTHOR("Henry Kupis <fe-pi@cox.net>");
++MODULE_DESCRIPTION("ASoC Driver for Fe-Pi Audio");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/brcm2708/patches-4.9/0193-Add-overlay-for-ads1115-ADCs-1864.patch b/target/linux/brcm2708/patches-4.9/0193-Add-overlay-for-ads1115-ADCs-1864.patch
new file mode 100644
index 0000000000..39d48e60b3
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0193-Add-overlay-for-ads1115-ADCs-1864.patch
@@ -0,0 +1,159 @@
+From 6d5e32067cf3f3169ec15097c175878de365d247 Mon Sep 17 00:00:00 2001
+From: Scott Ellis <scott@jumpnowtek.com>
+Date: Wed, 1 Mar 2017 07:22:24 -0500
+Subject: [PATCH] Add overlay for ads1115 ADCs (#1864)
+
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 22 ++++++
+ arch/arm/boot/dts/overlays/ads1115-overlay.dts | 103 +++++++++++++++++++++++++
+ 3 files changed, 126 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/ads1115-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -4,6 +4,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ adau1977-adc.dtbo \
+ adau7002-simple.dtbo \
+ ads1015.dtbo \
++ ads1115.dtbo \
+ ads7846.dtbo \
+ akkordion-iqdacplus.dtbo \
+ allo-piano-dac-pcm512x-audio.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -196,6 +196,28 @@ Params: addr I2C bus
+ http://www.ti.com/lit/ds/symlink/ads1015.pdf
+
+
++Name: ads1115
++Info: Texas Instruments ADS1115 ADC
++Load: dtoverlay=ads1115,<param>[=<val>]
++Params: addr I2C bus address of device. Set based on how the
++ addr pin is wired. (default=0x48 assumes addr
++ is pulled to GND)
++ cha_enable Enable virtual channel a.
++ cha_cfg Set the configuration for virtual channel a.
++ (default=4 configures this channel for the
++ voltage at A0 with respect to GND)
++ cha_datarate Set the datarate (samples/sec) for this channel.
++ (default=7 sets 860 sps)
++ cha_gain Set the gain of the Programmable Gain
++ Amplifier for this channel. (Default 1 sets the
++ full scale of the channel to 4.096 Volts)
++
++ Channel parameters can be set for each enabled channel.
++ A maximum of 4 channels can be enabled (letters a thru d).
++ For more information refer to the device datasheet at:
++ http://www.ti.com/lit/ds/symlink/ads1115.pdf
++
++
+ Name: ads7846
+ Info: ADS7846 Touch controller
+ Load: dtoverlay=ads7846,<param>=<val>
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/ads1115-overlay.dts
+@@ -0,0 +1,103 @@
++/*
++ * TI ADS1115 multi-channel ADC overlay
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2708";
++
++ fragment@0 {
++ target = <&i2c_arm>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ ads1115: ads1115 {
++ compatible = "ti,ads1115";
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x48>;
++ };
++ };
++ };
++
++ fragment@1 {
++ target-path = "i2c_arm/ads1115";
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ channel_a: channel_a {
++ reg = <4>;
++ ti,gain = <1>;
++ ti,datarate = <7>;
++ };
++ };
++ };
++
++ fragment@2 {
++ target-path = "i2c_arm/ads1115";
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ channel_b: channel_b {
++ reg = <5>;
++ ti,gain = <1>;
++ ti,datarate = <7>;
++ };
++ };
++ };
++
++ fragment@3 {
++ target-path = "i2c_arm/ads1115";
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ channel_c: channel_c {
++ reg = <6>;
++ ti,gain = <1>;
++ ti,datarate = <7>;
++ };
++ };
++ };
++
++ fragment@4 {
++ target-path = "i2c_arm/ads1115";
++ __dormant__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ channel_d: channel_d {
++ reg = <7>;
++ ti,gain = <1>;
++ ti,datarate = <7>;
++ };
++ };
++ };
++
++ __overrides__ {
++ addr = <&ads1115>,"reg:0";
++ cha_enable = <0>,"=1";
++ cha_cfg = <&channel_a>,"reg:0";
++ cha_gain = <&channel_a>,"ti,gain:0";
++ cha_datarate = <&channel_a>,"ti,datarate:0";
++ chb_enable = <0>,"=2";
++ chb_cfg = <&channel_b>,"reg:0";
++ chb_gain = <&channel_b>,"ti,gain:0";
++ chb_datarate = <&channel_b>,"ti,datarate:0";
++ chc_enable = <0>,"=3";
++ chc_cfg = <&channel_c>,"reg:0";
++ chc_gain = <&channel_c>,"ti,gain:0";
++ chc_datarate = <&channel_c>,"ti,datarate:0";
++ chd_enable = <0>,"=4";
++ chd_cfg = <&channel_d>,"reg:0";
++ chd_gain = <&channel_d>,"ti,gain:0";
++ chd_datarate = <&channel_d>,"ti,datarate:0";
++ };
++};
diff --git a/target/linux/brcm2708/patches-4.9/0194-clk-bcm2835-Correct-the-prediv-logic.patch b/target/linux/brcm2708/patches-4.9/0194-clk-bcm2835-Correct-the-prediv-logic.patch
new file mode 100644
index 0000000000..c81194fe69
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0194-clk-bcm2835-Correct-the-prediv-logic.patch
@@ -0,0 +1,27 @@
+From a9913dccdeaabca37343d0d8b0a48cda1e434e02 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 1 Mar 2017 16:06:53 +0000
+Subject: [PATCH] clk-bcm2835: Correct the prediv logic
+
+If a clock has the prediv flag set, both the integer and fractional
+parts must be scaled when calculating the resulting frequency.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/clk/bcm/clk-bcm2835.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -616,8 +616,10 @@ static unsigned long bcm2835_pll_get_rat
+ using_prediv = cprman_read(cprman, data->ana_reg_base + 4) &
+ data->ana->fb_prediv_mask;
+
+- if (using_prediv)
++ if (using_prediv) {
+ ndiv *= 2;
++ fdiv *= 2;
++ }
+
+ return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv);
+ }
diff --git a/target/linux/brcm2708/patches-4.9/0195-amba_pl011-Round-input-clock-up.patch b/target/linux/brcm2708/patches-4.9/0195-amba_pl011-Round-input-clock-up.patch
new file mode 100644
index 0000000000..2bd501d8db
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0195-amba_pl011-Round-input-clock-up.patch
@@ -0,0 +1,86 @@
+From 0360d687752df3c5546dd1534904a6e0168b6360 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 1 Mar 2017 16:07:39 +0000
+Subject: [PATCH] amba_pl011: Round input clock up
+
+The UART clock is initialised to be as close to the requested
+frequency as possible without exceeding it. Now that there is a
+clock manager that returns the actual frequencies, an expected
+48MHz clock is reported as 47999625. If the requested baudrate
+== requested clock/16, there is no headroom and the slight
+reduction in actual clock rate results in failure.
+
+Detect cases where it looks like a "round" clock was chosen and
+adjust the reported clock to match that "round" value. As the
+code comment says:
+
+/*
+ * If increasing a clock by less than 0.1% changes it
+ * from ..999.. to ..000.., round up.
+ */
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1646,6 +1646,23 @@ static void pl011_put_poll_char(struct u
+
+ #endif /* CONFIG_CONSOLE_POLL */
+
++unsigned long pl011_clk_round(unsigned long clk)
++{
++ unsigned long scaler;
++
++ /*
++ * If increasing a clock by less than 0.1% changes it
++ * from ..999.. to ..000.., round up.
++ */
++ scaler = 1;
++ while (scaler * 100000 < clk)
++ scaler *= 10;
++ if ((clk + scaler - 1)/scaler % 1000 == 0)
++ clk = (clk/scaler + 1) * scaler;
++
++ return clk;
++}
++
+ static int pl011_hwinit(struct uart_port *port)
+ {
+ struct uart_amba_port *uap =
+@@ -1662,7 +1679,7 @@ static int pl011_hwinit(struct uart_port
+ if (retval)
+ return retval;
+
+- uap->port.uartclk = clk_get_rate(uap->clk);
++ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
+
+ /* Clear pending error and receive interrupts */
+ pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS |
+@@ -2300,7 +2317,7 @@ static int __init pl011_console_setup(st
+ plat->init();
+ }
+
+- uap->port.uartclk = clk_get_rate(uap->clk);
++ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
+
+ if (uap->vendor->fixed_options) {
+ baud = uap->fixed_baud;
+@@ -2372,6 +2389,7 @@ static struct uart_driver amba_reg = {
+ .cons = AMBA_CONSOLE,
+ };
+
++#if 0
+ static int pl011_probe_dt_alias(int index, struct device *dev)
+ {
+ struct device_node *np;
+@@ -2403,6 +2421,7 @@ static int pl011_probe_dt_alias(int inde
+
+ return ret;
+ }
++#endif
+
+ /* unregisters the driver also if no more ports are left */
+ static void pl011_unregister_port(struct uart_amba_port *uap)
diff --git a/target/linux/brcm2708/patches-4.9/0196-BCM2835-V4L2-Ensure-H264-header-bytes-get-a-sensible.patch b/target/linux/brcm2708/patches-4.9/0196-BCM2835-V4L2-Ensure-H264-header-bytes-get-a-sensible.patch
new file mode 100644
index 0000000000..df8d4b4a4f
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0196-BCM2835-V4L2-Ensure-H264-header-bytes-get-a-sensible.patch
@@ -0,0 +1,87 @@
+From 02ceda02182f6cb538be397b8d8f34b64a254559 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Mon, 13 Feb 2017 11:10:50 +0000
+Subject: [PATCH] BCM2835-V4L2: Ensure H264 header bytes get a sensible
+ timestamp
+
+H264 header come off VC with 0 timestamps, which means they get a
+strange timestamp when processed with VC/kernel start times,
+particularly if used with the inline header option.
+Remember the last frame timestamp and use that if set, or otherwise
+use the kernel start time.
+
+https://github.com/raspberrypi/linux/issues/1836
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ drivers/media/platform/bcm2835/bcm2835-camera.c | 30 ++++++++++++++++++++++---
+ drivers/media/platform/bcm2835/bcm2835-camera.h | 2 ++
+ 2 files changed, 29 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-camera.c
++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
+@@ -356,8 +356,13 @@ static void buffer_cb(struct vchiq_mmal_
+ }
+ } else {
+ if (dev->capture.frame_count) {
+- if (dev->capture.vc_start_timestamp != -1 &&
+- pts != 0) {
++ if (dev->capture.vc_start_timestamp == -1) {
++ buf->vb.vb2_buf.timestamp = ktime_get_ns();
++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
++ "Buffer time set as current time - %lld",
++ buf->vb.vb2_buf.timestamp);
++
++ } else if(pts != 0) {
+ struct timeval timestamp;
+ s64 runtime_us = pts -
+ dev->capture.vc_start_timestamp;
+@@ -390,10 +395,27 @@ static void buffer_cb(struct vchiq_mmal_
+ buf->vb.vb2_buf.timestamp = timestamp.tv_sec * 1000000000ULL +
+ timestamp.tv_usec * 1000ULL;
+ } else {
+- buf->vb.vb2_buf.timestamp = ktime_get_ns();
++ if (dev->capture.last_timestamp) {
++ buf->vb.vb2_buf.timestamp = dev->capture.last_timestamp;
++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
++ "Buffer time set as last timestamp - %lld",
++ buf->vb.vb2_buf.timestamp);
++ }
++ else {
++ buf->vb.vb2_buf.timestamp =
++ dev->capture.kernel_start_ts.tv_sec * 1000000000ULL +
++ dev->capture.kernel_start_ts.tv_usec * 1000ULL;
++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
++ "Buffer time set as start timestamp - %lld",
++ buf->vb.vb2_buf.timestamp);
++ }
+ }
++ dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp;
+
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length);
++ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
++ "Buffer has ts %llu",
++ dev->capture.last_timestamp);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+ if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS &&
+@@ -559,6 +581,8 @@ static int start_streaming(struct vb2_qu
+ "Start time %lld size %d\n",
+ dev->capture.vc_start_timestamp, parameter_size);
+
++ dev->capture.last_timestamp = 0;
++
+ v4l2_get_timestamp(&dev->capture.kernel_start_ts);
+
+ /* enable the camera port */
+--- a/drivers/media/platform/bcm2835/bcm2835-camera.h
++++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
+@@ -93,6 +93,8 @@ struct bm2835_mmal_dev {
+ s64 vc_start_timestamp;
+ /* Kernel start timestamp for streaming */
+ struct timeval kernel_start_ts;
++ /* Timestamp of last frame */
++ u64 last_timestamp;
+
+ struct vchiq_mmal_port *port; /* port being used for capture */
+ /* camera port being used for capture */
diff --git a/target/linux/brcm2708/patches-4.9/0197-BCM2835-V4L2-Correctly-denote-key-frames-in-encoded-.patch b/target/linux/brcm2708/patches-4.9/0197-BCM2835-V4L2-Correctly-denote-key-frames-in-encoded-.patch
new file mode 100644
index 0000000000..4b375abad9
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0197-BCM2835-V4L2-Correctly-denote-key-frames-in-encoded-.patch
@@ -0,0 +1,24 @@
+From 9136b739f4ecc714db0431a3e0f4f4d9b12ab670 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Mon, 13 Feb 2017 13:11:41 +0000
+Subject: [PATCH] BCM2835-V4L2: Correctly denote key frames in encoded data
+
+Forward MMAL key frame flags to the V4L2 buffers.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ drivers/media/platform/bcm2835/bcm2835-camera.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/media/platform/bcm2835/bcm2835-camera.c
++++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
+@@ -413,6 +413,9 @@ static void buffer_cb(struct vchiq_mmal_
+ dev->capture.last_timestamp = buf->vb.vb2_buf.timestamp;
+
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length);
++ if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
++ buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
++
+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+ "Buffer has ts %llu",
+ dev->capture.last_timestamp);
diff --git a/target/linux/brcm2708/patches-4.9/0198-bcm2835-gpio-exp-Driver-for-GPIO-expander-via-mailbo.patch b/target/linux/brcm2708/patches-4.9/0198-bcm2835-gpio-exp-Driver-for-GPIO-expander-via-mailbo.patch
new file mode 100644
index 0000000000..3d09d1dc3f
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0198-bcm2835-gpio-exp-Driver-for-GPIO-expander-via-mailbo.patch
@@ -0,0 +1,405 @@
+From 2f8f62fbd42a55825da437faba4b6164f2e0bee9 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Mon, 20 Feb 2017 17:01:21 +0000
+Subject: [PATCH] bcm2835-gpio-exp: Driver for GPIO expander via mailbox
+ service
+
+Pi3 and Compute Module 3 have a GPIO expander that the
+VPU communicates with.
+There is a mailbox service that now allows control of this
+expander, so add a kernel driver that can make use of it.
+
+Pwr_led node added to device-tree for Pi3.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 22 +++
+ arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 10 +-
+ arch/arm/configs/bcm2709_defconfig | 1 +
+ drivers/gpio/Kconfig | 7 +
+ drivers/gpio/Makefile | 1 +
+ drivers/gpio/gpio-bcm-exp.c | 256 +++++++++++++++++++++++++++++
+ include/soc/bcm2835/raspberrypi-firmware.h | 4 +
+ 7 files changed, 300 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/gpio/gpio-bcm-exp.c
+
+--- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts
+@@ -96,6 +96,14 @@
+ firmware = <&firmware>;
+ status = "okay";
+ };
++
++ expgpio: expgpio {
++ compatible = "brcm,bcm2835-expgpio";
++ gpio-controller;
++ #gpio-cells = <2>;
++ firmware = <&firmware>;
++ status = "okay";
++ };
+ };
+
+ &fb {
+@@ -163,6 +171,16 @@
+ linux,default-trigger = "mmc0";
+ gpios = <&virtgpio 0 0>;
+ };
++
++ pwr_led: pwr {
++ label = "led1";
++ linux,default-trigger = "input";
++ gpios = <&expgpio 7 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&hdmi {
++ hpd-gpios = <&expgpio 4 GPIO_ACTIVE_LOW>;
+ };
+
+ &audio {
+@@ -193,6 +211,10 @@
+ act_led_activelow = <&act_led>,"gpios:8";
+ act_led_trigger = <&act_led>,"linux,default-trigger";
+
++ pwr_led_gpio = <&pwr_led>,"gpios:4";
++ pwr_led_activelow = <&pwr_led>,"gpios:8";
++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger";
++
+ audio = <&audio>,"status";
+ watchdog = <&watchdog>,"status";
+ random = <&random>,"status";
+--- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
++++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts
+@@ -65,6 +65,14 @@
+ firmware = <&firmware>;
+ status = "okay";
+ };
++
++ expgpio: expgpio {
++ compatible = "brcm,bcm2835-expgpio";
++ gpio-controller;
++ #gpio-cells = <2>;
++ firmware = <&firmware>;
++ status = "okay";
++ };
+ };
+
+ &fb {
+@@ -123,7 +131,7 @@
+ };
+
+ &hdmi {
+- hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
++ hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>;
+ };
+
+ &audio {
+--- a/arch/arm/configs/bcm2709_defconfig
++++ b/arch/arm/configs/bcm2709_defconfig
+@@ -625,6 +625,7 @@ CONFIG_PPS=m
+ CONFIG_PPS_CLIENT_LDISC=m
+ CONFIG_PPS_CLIENT_GPIO=m
+ CONFIG_GPIO_SYSFS=y
++CONFIG_GPIO_BCM_EXP=y
+ CONFIG_GPIO_BCM_VIRT=y
+ CONFIG_GPIO_ARIZONA=m
+ CONFIG_GPIO_STMPE=y
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -128,6 +128,13 @@ config GPIO_AXP209
+ help
+ Say yes to enable GPIO support for the AXP209 PMIC
+
++config GPIO_BCM_EXP
++ bool "Broadcom Exp GPIO"
++ depends on OF_GPIO && RASPBERRYPI_FIRMWARE && (ARCH_BCM2835 || COMPILE_TEST)
++ help
++ Turn on GPIO support for Broadcom chips using the firmware mailbox
++ to communicate with VideoCore on BCM283x chips.
++
+ config GPIO_BCM_KONA
+ bool "Broadcom Kona GPIO"
+ depends on OF_GPIO && (ARCH_BCM_MOBILE || COMPILE_TEST)
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -30,6 +30,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizo
+ obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o
+ obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o
+ obj-$(CONFIG_GPIO_AXP209) += gpio-axp209.o
++obj-$(CONFIG_GPIO_BCM_EXP) += gpio-bcm-exp.o
+ obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
+ obj-$(CONFIG_GPIO_BCM_VIRT) += gpio-bcm-virt.o
+ obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
+--- /dev/null
++++ b/drivers/gpio/gpio-bcm-exp.c
+@@ -0,0 +1,256 @@
++/*
++ * Broadcom expander GPIO driver
++ *
++ * Uses the firmware mailbox service to communicate with the
++ * GPIO expander on the VPU.
++ *
++ * Copyright (C) 2017 Raspberry Pi Trading Ltd.
++ *
++ * Author: Dave Stevenson <dave.stevenson@raspberrypi.org>
++ * Based on gpio-bcm-virt.c by Dom Cobley <popcornmix@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <soc/bcm2835/raspberrypi-firmware.h>
++
++#define MODULE_NAME "brcmexp-gpio"
++#define NUM_GPIO 8
++
++struct brcmexp_gpio {
++ struct gpio_chip gc;
++ struct device *dev;
++ struct rpi_firmware *fw;
++};
++
++struct gpio_set_config {
++ u32 gpio, direction, polarity, term_en, term_pull_up, state;
++};
++
++struct gpio_get_config {
++ u32 gpio, direction, polarity, term_en, term_pull_up;
++};
++
++struct gpio_get_set_state {
++ u32 gpio, state;
++};
++
++static int brcmexp_gpio_get_polarity(struct gpio_chip *gc, unsigned int off)
++{
++ struct brcmexp_gpio *gpio;
++ struct gpio_get_config get;
++ int ret;
++
++ gpio = container_of(gc, struct brcmexp_gpio, gc);
++
++ get.gpio = off + gpio->gc.base; /* GPIO to update */
++
++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
++ &get, sizeof(get));
++ if (ret) {
++ dev_err(gpio->dev,
++ "Failed to get GPIO %u config (%d)\n", off, ret);
++ return ret;
++ }
++ return get.polarity;
++}
++
++static int brcmexp_gpio_dir_in(struct gpio_chip *gc, unsigned int off)
++{
++ struct brcmexp_gpio *gpio;
++ struct gpio_set_config set_in;
++ int ret;
++
++ gpio = container_of(gc, struct brcmexp_gpio, gc);
++
++ set_in.gpio = off + gpio->gc.base; /* GPIO to update */
++ set_in.direction = 0; /* Input */
++ set_in.polarity = brcmexp_gpio_get_polarity(gc, off);
++ /* Retain existing setting */
++ set_in.term_en = 0; /* termination disabled */
++ set_in.term_pull_up = 0; /* n/a as termination disabled */
++ set_in.state = 0; /* n/a as configured as an input */
++
++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
++ &set_in, sizeof(set_in));
++ if (ret) {
++ dev_err(gpio->dev,
++ "Failed to set GPIO %u to input (%d)\n",
++ off, ret);
++ return ret;
++ }
++ return 0;
++}
++
++static int brcmexp_gpio_dir_out(struct gpio_chip *gc, unsigned int off, int val)
++{
++ struct brcmexp_gpio *gpio;
++ struct gpio_set_config set_out;
++ int ret;
++
++ gpio = container_of(gc, struct brcmexp_gpio, gc);
++
++ set_out.gpio = off + gpio->gc.base; /* GPIO to update */
++ set_out.direction = 1; /* Output */
++ set_out.polarity = brcmexp_gpio_get_polarity(gc, off);
++ /* Retain existing setting */
++ set_out.term_en = 0; /* n/a as an output */
++ set_out.term_pull_up = 0; /* n/a as termination disabled */
++ set_out.state = val; /* Output state */
++
++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_CONFIG,
++ &set_out, sizeof(set_out));
++ if (ret) {
++ dev_err(gpio->dev,
++ "Failed to set GPIO %u to output (%d)\n", off, ret);
++ return ret;
++ }
++ return 0;
++}
++
++static int brcmexp_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
++{
++ struct brcmexp_gpio *gpio;
++ struct gpio_get_config get;
++ int ret;
++
++ gpio = container_of(gc, struct brcmexp_gpio, gc);
++
++ get.gpio = off + gpio->gc.base; /* GPIO to update */
++
++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_CONFIG,
++ &get, sizeof(get));
++ if (ret) {
++ dev_err(gpio->dev,
++ "Failed to get GPIO %u config (%d)\n", off, ret);
++ return ret;
++ }
++ return get.direction ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
++}
++
++static int brcmexp_gpio_get(struct gpio_chip *gc, unsigned int off)
++{
++ struct brcmexp_gpio *gpio;
++ struct gpio_get_set_state get;
++ int ret;
++
++ gpio = container_of(gc, struct brcmexp_gpio, gc);
++
++ get.gpio = off + gpio->gc.base; /* GPIO to update */
++ get.state = 0; /* storage for returned value */
++
++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_GET_GPIO_STATE,
++ &get, sizeof(get));
++ if (ret) {
++ dev_err(gpio->dev,
++ "Failed to get GPIO %u state (%d)\n", off, ret);
++ return ret;
++ }
++ return !!get.state;
++}
++
++static void brcmexp_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
++{
++ struct brcmexp_gpio *gpio;
++ struct gpio_get_set_state set;
++ int ret;
++
++ gpio = container_of(gc, struct brcmexp_gpio, gc);
++
++ off += gpio->gc.base;
++
++ set.gpio = off + gpio->gc.base; /* GPIO to update */
++ set.state = val; /* Output state */
++
++ ret = rpi_firmware_property(gpio->fw, RPI_FIRMWARE_SET_GPIO_STATE,
++ &set, sizeof(set));
++ if (ret)
++ dev_err(gpio->dev,
++ "Failed to set GPIO %u state (%d)\n", off, ret);
++}
++
++static int brcmexp_gpio_probe(struct platform_device *pdev)
++{
++ int err = 0;
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct device_node *fw_node;
++ struct rpi_firmware *fw;
++ struct brcmexp_gpio *ucb;
++
++ fw_node = of_parse_phandle(np, "firmware", 0);
++ if (!fw_node) {
++ dev_err(dev, "Missing firmware node\n");
++ return -ENOENT;
++ }
++
++ fw = rpi_firmware_get(fw_node);
++ if (!fw)
++ return -EPROBE_DEFER;
++
++ ucb = devm_kzalloc(dev, sizeof(*ucb), GFP_KERNEL);
++ if (!ucb)
++ return -EINVAL;
++
++ ucb->fw = fw;
++ ucb->dev = dev;
++ ucb->gc.label = MODULE_NAME;
++ ucb->gc.owner = THIS_MODULE;
++ ucb->gc.of_node = np;
++ ucb->gc.base = 128;
++ ucb->gc.ngpio = NUM_GPIO;
++
++ ucb->gc.direction_input = brcmexp_gpio_dir_in;
++ ucb->gc.direction_output = brcmexp_gpio_dir_out;
++ ucb->gc.get_direction = brcmexp_gpio_get_direction;
++ ucb->gc.get = brcmexp_gpio_get;
++ ucb->gc.set = brcmexp_gpio_set;
++ ucb->gc.can_sleep = true;
++
++ err = gpiochip_add(&ucb->gc);
++ if (err)
++ return err;
++
++ platform_set_drvdata(pdev, ucb);
++
++ return 0;
++}
++
++static int brcmexp_gpio_remove(struct platform_device *pdev)
++{
++ struct brcmexp_gpio *ucb = platform_get_drvdata(pdev);
++
++ gpiochip_remove(&ucb->gc);
++
++ return 0;
++}
++
++static const struct of_device_id __maybe_unused brcmexp_gpio_ids[] = {
++ { .compatible = "brcm,bcm2835-expgpio" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, brcmexp_gpio_ids);
++
++static struct platform_driver brcmexp_gpio_driver = {
++ .driver = {
++ .name = MODULE_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(brcmexp_gpio_ids),
++ },
++ .probe = brcmexp_gpio_probe,
++ .remove = brcmexp_gpio_remove,
++};
++module_platform_driver(brcmexp_gpio_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.org>");
++MODULE_DESCRIPTION("brcm-exp GPIO driver");
++MODULE_ALIAS("platform:brcmexp-gpio");
+--- a/include/soc/bcm2835/raspberrypi-firmware.h
++++ b/include/soc/bcm2835/raspberrypi-firmware.h
+@@ -83,7 +83,11 @@ enum rpi_firmware_property_tag {
+ RPI_FIRMWARE_SET_TURBO = 0x00038009,
+ RPI_FIRMWARE_SET_CUSTOMER_OTP = 0x00038021,
+ RPI_FIRMWARE_SET_DOMAIN_STATE = 0x00038030,
++ RPI_FIRMWARE_GET_GPIO_STATE = 0x00030041,
++ RPI_FIRMWARE_SET_GPIO_STATE = 0x00038041,
+ RPI_FIRMWARE_SET_SDHOST_CLOCK = 0x00038042,
++ RPI_FIRMWARE_GET_GPIO_CONFIG = 0x00030043,
++ RPI_FIRMWARE_SET_GPIO_CONFIG = 0x00038043,
+
+ /* Dispmanx TAGS */
+ RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
diff --git a/target/linux/brcm2708/patches-4.9/0199-BCM270X_DT-Add-bcm2708-rpi-0-w.dts.patch b/target/linux/brcm2708/patches-4.9/0199-BCM270X_DT-Add-bcm2708-rpi-0-w.dts.patch
new file mode 100644
index 0000000000..c3a87517e2
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.9/0199-BCM270X_DT-Add-bcm2708-rpi-0-w.dts.patch
@@ -0,0 +1,225 @@
+From 41620ad7f4b059be162f615a7be423df78406d29 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Tue, 24 May 2016 16:30:05 +0100
+Subject: [PATCH] BCM270X_DT: Add bcm2708-rpi-0-w.dts
+
+Add DT support for the Pi Zero W. N.B. It will not be loaded
+automatically without a corresponding change to the firmware.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ arch/arm/boot/dts/Makefile | 1 +
+ arch/arm/boot/dts/bcm2708-rpi-0-w.dts | 197 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 198 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm2708-rpi-0-w.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2708-rpi-b.dtb \
+ bcm2708-rpi-b-plus.dtb \
+ bcm2708-rpi-cm.dtb \
++ bcm2708-rpi-0-w.dtb \
+ bcm2709-rpi-2-b.dtb \
+ bcm2710-rpi-3-b.dtb \
+ bcm2710-rpi-cm3.dtb
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2708-rpi-0-w.dts
+@@ -0,0 +1,197 @@
++/dts-v1/;
++
++#include "bcm2708.dtsi"
++
++/ {
++ model = "Raspberry Pi Zero W";
++};
++
++&gpio {
++ sdhost_pins: sdhost_pins {
++ brcm,pins = <48 49 50 51 52 53>;
++ brcm,function = <4>; /* alt0 */
++ };
++
++ spi0_pins: spi0_pins {
++ brcm,pins = <9 10 11>;
++ brcm,function = <4>; /* alt0 */
++ };
++
++ spi0_cs_pins: spi0_cs_pins {
++ brcm,pins = <8 7>;
++ brcm,function = <1>; /* output */
++ };
++
++ i2c0_pins: i2c0 {
++ brcm,pins = <0 1>;
++ brcm,function = <4>;
++ };
++
++ i2c1_pins: i2c1 {
++ brcm,pins = <2 3>;
++ brcm,function = <4>;
++ };
++
++ i2s_pins: i2s {
++ brcm,pins = <18 19 20 21>;
++ brcm,function = <4>; /* alt0 */
++ };
++
++ sdio_pins: sdio_pins {
++ brcm,pins = <34 35 36 37 38 39>;
++ brcm,function = <7>; /* ALT3 = SD1 */
++ brcm,pull = <0 2 2 2 2 2>;
++ };
++
++ bt_pins: bt_pins {
++ brcm,pins = <43>;
++ brcm,function = <4>; /* alt0:GPCLK2 */
++ brcm,pull = <0>; /* none */
++ };
++
++ uart0_pins: uart0_pins {
++ brcm,pins = <30 31 32 33>;
++ brcm,function = <7>; /* alt3=UART0 */
++ brcm,pull = <2 0 0 2>; /* up none none up */
++ };
++
++ uart1_pins: uart1_pins {
++ brcm,pins;
++ brcm,function;
++ brcm,pull;
++ };
++
++ audio_pins: audio_pins {
++ brcm,pins = <>;
++ brcm,function = <>;
++ };
++};
++
++&sdhost {
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhost_pins>;
++ bus-width = <4>;
++ status = "okay";
++};
++
++&mmc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio_pins>;
++ non-removable;
++ bus-width = <4>;
++ status = "okay";
++};
++
++&fb {
++ status = "okay";
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins &bt_pins>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_pins>;
++ status = "okay";
++};
++
++&spi0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
++
++ spidev0: spidev@0{
++ compatible = "spidev";
++ reg = <0>; /* CE0 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <500000>;
++ };
++
++ spidev1: spidev@1{
++ compatible = "spidev";
++ reg = <1>; /* CE1 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <500000>;
++ };
++};
++
++&i2c0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0_pins>;
++ clock-frequency = <100000>;
++};
++
++&i2c1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ clock-frequency = <100000>;
++};
++
++&i2c2 {
++ clock-frequency = <100000>;
++};
++
++&i2s {
++ #sound-dai-cells = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s_pins>;
++};
++
++&random {
++ status = "okay";
++};
++
++&leds {
++ act_led: act {
++ label = "led0";
++ linux,default-trigger = "mmc0";
++ gpios = <&gpio 47 0>;
++ };
++};
++
++&hdmi {
++ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
++};
++
++&audio {
++ pinctrl-names = "default";
++ pinctrl-0 = <&audio_pins>;
++};
++
++/ {
++ chosen {
++ bootargs = "8250.nr_uarts=1";
++ };
++};
++
++/ {
++ __overrides__ {
++ uart0 = <&uart0>,"status";
++ uart1 = <&uart1>,"status";
++ i2s = <&i2s>,"status";
++ spi = <&spi0>,"status";
++ i2c0 = <&i2c0>,"status";
++ i2c1 = <&i2c1>,"status";
++ i2c2_iknowwhatimdoing = <&i2c2>,"status";
++ i2c0_baudrate = <&i2c0>,"clock-frequency:0";
++ i2c1_baudrate = <&i2c1>,"clock-frequency:0";
++ i2c2_baudrate = <&i2c2>,"clock-frequency:0";
++
++ act_led_gpio = <&act_led>,"gpios:4";
++ act_led_activelow = <&act_led>,"gpios:8";
++ act_led_trigger = <&act_led>,"linux,default-trigger";
++
++ audio = <&audio>,"status";
++ watchdog = <&watchdog>,"status";
++ random = <&random>,"status";
++ sd_overclock = <&sdhost>,"brcm,overclock-50:0";
++ sd_force_pio = <&sdhost>,"brcm,force-pio?";
++ sd_pio_limit = <&sdhost>,"brcm,pio-limit:0";
++ sd_debug = <&sdhost>,"brcm,debug";
++ };
++};