diff options
Diffstat (limited to 'target')
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 2a866e4..ecc6242 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 1619ba9..c1bed07 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 dffc368..0c9adec 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 04d0da8..e07d8cf 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 e2b3fdb..a49f9d4 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 b8b424b..a5737e3 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 9d47276..fc7ac4d 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 dbcf303..8075dff 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 f46579b..4b80ab0 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 376d6a8..b271d26 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 3ebcb0a..5f5bd83 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 a25275f..56be640 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 710e73a..9c7515f 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 be8e903..447f1ce 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 978d675..319eafb 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 67cc420..b29aa8d 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 e16f89a..d2b764f 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 bac0573..4eb4923 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 9b8e869..62145a2 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 3ec3537..5d4062c 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 4143498..08577fc 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 1311ccb..cd14dcc 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 e3bde68..e800713 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 deb271c..37eb154 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 94862f5..dfa312b 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 8c197fc..4992165 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 160c576..392ce70 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 dee1fed..d29517e 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 120f25d..90c0a0e 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 d4f4fec..9b2a613 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 1fb2184..97309da 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 16d32cc..0f5afac 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 4eecc14..c193ef9 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 81d48b7..20e5419 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 971581a..0610d03 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 a306868..b7c05c1 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 d21f187..a2f4551 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 00920a6..70fb8f3 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 c6ceef0..c4597ec 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 100c8b1..d84a0fe 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 87b62dc..50bad76 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 c951b6f..58b45de 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 fbfddde..6a22bdf 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 d7bce81..ff1cfad 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 66949f5..618cb9f 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 7a05db4..3d75e70 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 312a294..69f68c7 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 dee3c1d..ec6010a 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 ea529b8..0cbc1c4 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 8929ee2..7c5691c 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 fa826cb..ff6084f 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 acb199d..b86fb40 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 cd62abe..c37c0f6 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 3e47d68..ecaf614 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 2e77160..e6baeab 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 6feda0e..7ae4edd 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 5fdf024..ed4b270 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 6767122..d9d1fa9 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 50a0ed7..725ac70 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 44414e5..3434690 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 f0e7392..8d6337a 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 5c3e064..408ac04 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 ec376d4..a9906f3 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 a2eca8a..73c9ede 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 e9f3419..444c64e 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 3d98c22..43ed3fa 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 2d92f77..a7ce64b 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 3a86d97..5d73a28 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 77079e0..b5ae3f9 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 22f8654..107ed28 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 0353820..26ae5b3 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 7accb99..1be734b 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 d9dc426..5f8477c 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 483fc6e..08bf856 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 51d731a..edfb9f5 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 daccc7c..21d30af 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 fb823d2..9826be5 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 4123987..0000000 --- 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 1dfed15..d4f7e76 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 b23ff22..b8db1d5 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 32bc86a..de68bbf 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 95bf9a5..9654587 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 54d659f..1b87b13 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 207cc66..71d4fef 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 e931c99..f6a23f9 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 55d32df..45a5a37 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 39366ab..b06cd35 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 7455fa9..64e785d 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 51d5733..21f4334 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 4706e7a..67c0e3f 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 ce523e2..425224e 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 1f69465..40963de8 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 c864eba..941047a 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 0ebf29c..780a211 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 c940298..da92f04 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 9c76d38..0cbb4d7 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 294689b..ef3c97d 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 fef600b..71c0e30 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 1f30478..f60af85 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 ea1731b..1b8647e 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 55d2f68..c8cc5b7 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 e5d9528..e80c414 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 4be551f..eccb792 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 52fd44a..8ec807e 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 5dc6f85..a316b40 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 0909929..0b9ef71 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 3d1e684..88952dc 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 7692a92..899c75e 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 0a616ff..6646d77 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 b8cbe10..acc2ade 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 946c316..a913c50 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 a481aaf..0cd5aa4 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 ef70b97..07016d9 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 35ab56c..afe2b22 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 3083067..f69a48f 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 2f84052..34ab47e 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 8ab8207..119b054 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 67b72c9..0319ca4 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 af5c3b3..f914bfc 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 4acafa5..bfda58a 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 c85bb44..2a3a6d8 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 d57bfe1..0000000 --- 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 473876b..4bc80be 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 0de8da0..0000000 --- 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 a60080c..96b298d 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 0cc0f88..0000000 --- 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 dff27b9..423db95 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 a309394..c947a74 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 e90767a..2fd8366 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 b4ade04..544ccf6 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 f0076ce..cec560e 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 c2ba65f..4fbc443 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 3d1bb7e..ab5e409 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 4bb85d0..a94fee4 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 6685bbb..d11ca6b 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 4850c3e..deae274 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 189b288..0000000 --- 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 0517099..53335b9 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 ed707a1..63df4a0 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 91a0019..6c50870 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 99e9414..4f122fc 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 ab64295..e4ef715 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 57b3605..560dc6c 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 cd82d4f..1ed31c2 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 19d23fc..8c2d162 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 4c8cba1..bcd766f 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 0deaa0a..062e6e0 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 d865199..4c123b4 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 5c343ba..863d107 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 c9e4fd1..be16a47 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 0000000..db9fd39 --- /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 0000000..0a08eb9 --- /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 0000000..52e36b5 --- /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 0000000..16d740a --- /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 0000000..295db59 --- /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 0000000..82f4628 --- /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 0000000..448b037 --- /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 0000000..ed082ab --- /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 0000000..01e2977 --- /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 0000000..154e061 --- /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 0000000..24e8aed --- /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 0000000..16c5ec5 --- /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 0000000..027e5c0 --- /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 0000000..1ba605b --- /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 0000000..444c287 --- /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 0000000..3d65f5e --- /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 0000000..3326dca --- /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 0000000..2b81578 --- /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 0000000..f6d738d --- /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 0000000..ea0f4f1 --- /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 0000000..3c66fef --- /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 0000000..c2499c1 --- /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 0000000..39e6f11 --- /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 0000000..db82c0c --- /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 0000000..0b5a853 --- /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 0000000..1a425ca --- /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 0000000..15243a3 --- /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 0000000..97ae4a4 --- /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 0000000..a2671f2 --- /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 0000000..8689450 --- /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 0000000..42c3965 --- /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 0000000..208ff58 --- /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 0000000..f3f1410 --- /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 0000000..73fbf2b --- /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 0000000..c0967b4 --- /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 0000000..000f3a8 --- /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 0000000..453d027 --- /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 0000000..76b1bf3 --- /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 0000000..13f6c11 --- /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 0000000..09dcfa7 --- /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 0000000..fa0d998 --- /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 0000000..1303bdc --- /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 0000000..021eb01 --- /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 0000000..eb6422a --- /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 0000000..be3618a --- /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 0000000..262dc14 --- /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 = <®_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 0000000..39d48e6 --- /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 0000000..c81194f --- /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 0000000..2bd501d --- /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 0000000..df8d4b4 --- /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 0000000..4b375ab --- /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 0000000..3d09d1d --- /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 0000000..c3a8751 --- /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"; ++ }; ++}; |